aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7')
-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
1980 files changed, 0 insertions, 582374 deletions
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