B
    \h                 @   sH   d Z ddlZddlmZ ddlmZ G dd deZG d	d
 d
eZdS )zGlobal database feature support policy.

Provides decorators to mark tests requiring specific feature support from the
target database.

External dialect test suites should subclass SuiteRequirements
to provide specific inclusion/exclusions.

    N   )
exclusions   )utilc               @   s   e Zd ZdS )RequirementsN)__name__
__module____qualname__ r
   r
   >lib/python3.7/site-packages/sqlalchemy/testing/requirements.pyr      s   r   c               @   s  e Zd Zedd Zedd Zedd Zedd Zed	d
 Zedd Z	edd Z
edd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Zed'd( Zed)d* Zed+d, Zed-d. Zed/d0 Zed1d2 Zed3d4 Zed5d6 Zed7d8 Zed9d: Z ed;d< Z!ed=d> Z"ed?d@ Z#edAdB Z$edCdD Z%edEdF Z&edGdH Z'edIdJ Z(edKdL Z)edMdN Z*edOdP Z+edQdR Z,edSdT Z-edUdV Z.edWdX Z/edYdZ Z0ed[d\ Z1ed]d^ Z2ed_d` Z3edadb Z4edcdd Z5ededf Z6edgdh Z7edidj Z8edkdl Z9edmdn Z:edodp Z;edqdr Z<edsdt Z=edudv Z>edwdx Z?edydz Z@ed{d| ZAed}d~ ZBedd ZCedd ZDedd ZEedd ZFedd ZGedd ZHedd ZIedd ZJedd ZKedd ZLedd ZMedd ZNedd ZOedd ZPedd ZQedd ZRedd ZSedd ZTedd ZUedd ZVedd ZWedd ZXedd ZYedd ZZedd Z[edd Z\edd Z]edd Z^edd Z_edd Z`edd Zaedd Zbedd Zcedd ZdeddĄ ZeeddƄ ZfeddȄ Zgeddʄ Zhedd̄ Ziedd΄ ZjeddЄ Zkedd҄ ZleddԄ Zmeddք Zndd؄ Zoeddڄ Zpedd܄ Zqeddބ Zredd Zsedd Ztedd Zuedd Zvedd Zwedd Zxedd Zyedd Zzedd Z{edd Z|dd Z}dd Z~edd Zedd Zdd Zdd ZdS (   SuiteRequirementsc             C   s   t  S )z/target platform can emit basic CreateTable DDL.)r   open)selfr
   r
   r   create_table   s    zSuiteRequirements.create_tablec             C   s   t  S )z-target platform can emit basic DropTable DDL.)r   r   )r   r
   r
   r   
drop_table#   s    zSuiteRequirements.drop_tablec             C   s   t  S )z*Target database must support foreign keys.)r   r   )r   r
   r
   r   foreign_keys)   s    zSuiteRequirements.foreign_keysc             C   s   t  S )zR"target database must support ON UPDATE..CASCADE behavior in
        foreign keys.)r   r   )r   r
   r
   r   on_update_cascade/   s    z#SuiteRequirements.on_update_cascadec             C   s   t  S )zWtarget database must *not* support ON UPDATE..CASCADE behavior in
        foreign keys.)r   closed)r   r
   r
   r   non_updating_cascade6   s    z&SuiteRequirements.non_updating_cascadec             C   s   t  S )N)r   r   )r   r
   r
   r   deferrable_fks<   s    z SuiteRequirements.deferrable_fksc                s   t  fddS )Nc                  s    j jp jjS )N)r   Zenabledr   r
   )r   r
   r   <lambda>F   s   z?SuiteRequirements.on_update_or_deferrable_fks.<locals>.<lambda>)r   only_if)r   r
   )r   r   on_update_or_deferrable_fks@   s    z-SuiteRequirements.on_update_or_deferrable_fksc             C   s   t  S )z;Target database must support self-referential foreign keys.)r   r   )r   r
   r
   r   self_referential_foreign_keysJ   s    z/SuiteRequirements.self_referential_foreign_keysc             C   s   t  S )z=Target database must support the DDL phrases for FOREIGN KEY.)r   r   )r   r
   r
   r   foreign_key_ddlP   s    z!SuiteRequirements.foreign_key_ddlc             C   s   t  S )z3target database must support names for constraints.)r   r   )r   r
   r
   r   named_constraintsV   s    z#SuiteRequirements.named_constraintsc             C   s   t  S )z(Target database must support subqueries.)r   r   )r   r
   r
   r   
subqueries\   s    zSuiteRequirements.subqueriesc             C   s   t  S )zRtarget database can render OFFSET, or an equivalent, in a
        SELECT.
        )r   r   )r   r
   r
   r   offsetb   s    zSuiteRequirements.offsetc             C   s   t  S )zWtarget database can render LIMIT and/or OFFSET using a bound
        parameter
        )r   r   )r   r
   r
   r   bound_limit_offsetj   s    z$SuiteRequirements.bound_limit_offsetc             C   s   t  S )zTarget database must support parenthesized SELECT in UNION
        when LIMIT/OFFSET is specifically present.

        E.g. (SELECT ...) UNION (SELECT ..)

        This is known to fail on SQLite.

        )r   r   )r   r
   r
   r   /parens_in_union_contained_select_w_limit_offsetr   s    
zASuiteRequirements.parens_in_union_contained_select_w_limit_offsetc             C   s   t  S )al  Target database must support parenthesized SELECT in UNION
        when OFFSET/LIMIT is specifically not present.

        E.g. (SELECT ... LIMIT ..) UNION (SELECT .. OFFSET ..)

        This is known to fail on SQLite.  It also fails on Oracle
        because without LIMIT/OFFSET, there is currently no step that
        creates an additional subquery.

        )r   r   )r   r
   r
   r   0parens_in_union_contained_select_wo_limit_offset~   s    zBSuiteRequirements.parens_in_union_contained_select_wo_limit_offsetc             C   s   t  S )z;Target database must support boolean expressions as columns)r   r   )r   r
   r
   r   boolean_col_expressions   s    z)SuiteRequirements.boolean_col_expressionsc             C   s   t  S )z,Target backends that support nulls ordering.)r   r   )r   r
   r
   r   nullsordering   s    zSuiteRequirements.nullsorderingc             C   s   t  S )ztarget database/driver supports bound parameters as column expressions
        without being in the context of a typed column.

        )r   r   )r   r
   r
   r   standalone_binds   s    z"SuiteRequirements.standalone_bindsc             C   s   t  S )z5Target database must support INTERSECT or equivalent.)r   r   )r   r
   r
   r   	intersect   s    zSuiteRequirements.intersectc             C   s   t  S )z?Target database must support EXCEPT or equivalent (i.e. MINUS).)r   r   )r   r
   r
   r   except_   s    zSuiteRequirements.except_c             C   s   t  S )z.Target database must support window functions.)r   r   )r   r
   r
   r   window_functions   s    z"SuiteRequirements.window_functionsc             C   s   t  S )zTarget database supports CTEs)r   r   )r   r
   r
   r   ctes   s    zSuiteRequirements.ctesc             C   s   t  S )ztarget database supports CTES that ride on top of a normal UPDATE
        or DELETE statement which refers to the CTE in a correlated subquery.

        )r   r   )r   r
   r
   r   ctes_with_update_delete   s    z)SuiteRequirements.ctes_with_update_deletec             C   s   t  S )z}target database supports CTES which consist of INSERT, UPDATE
        or DELETE *within* the CTE, e.g. WITH x AS (UPDATE....))r   r   )r   r
   r
   r   ctes_on_dml   s    zSuiteRequirements.ctes_on_dmlc             C   s   t  S )z~target platform generates new surrogate integer primary key values
        when insert() is executed, excluding the pk column.)r   r   )r   r
   r
   r   autoincrement_insert   s    z&SuiteRequirements.autoincrement_insertc             C   s   t  S )a#  target platform will allow cursor.fetchone() to proceed after a
        COMMIT.

        Typically this refers to an INSERT statement with RETURNING which
        is invoked within "autocommit".   If the row can be returned
        after the autocommit, then this rule can be open.

        )r   r   )r   r
   r
   r   fetch_rows_post_commit   s    z(SuiteRequirements.fetch_rows_post_commitc             C   s   t  S )ztarget platform supports SQL expressions in GROUP BY

        e.g.

        SELECT x + y AS somelabel FROM table GROUP BY x + y

        )r   r   )r   r
   r
   r   group_by_complex_expression   s    
z-SuiteRequirements.group_by_complex_expressionc             C   s   t dd dS )Nc             S   s   | j jj S )N)dbdialectZsupports_sane_rowcount)configr
   r
   r   r      s    z1SuiteRequirements.sane_rowcount.<locals>.<lambda>z&driver doesn't support 'sane' rowcount)r   skip_if)r   r
   r
   r   sane_rowcount   s    zSuiteRequirements.sane_rowcountc             C   s   t dd dS )Nc             S   s   | j jj S )N)r-   r.   Zsupports_sane_multi_rowcount)r/   r
   r
   r   r      s    z7SuiteRequirements.sane_multi_rowcount.<locals>.<lambda>z;driver %(driver)s %(doesnt_support)s 'sane' multi row count)r   fails_if)r   r
   r
   r   sane_multi_rowcount   s    z%SuiteRequirements.sane_multi_rowcountc             C   s   t dd dS )Nc             S   s   | j jj S )N)r-   r.   Z supports_sane_rowcount_returning)r/   r
   r
   r   r      s    z=SuiteRequirements.sane_rowcount_w_returning.<locals>.<lambda>z;driver doesn't support 'sane' rowcount when returning is on)r   r2   )r   r
   r
   r   sane_rowcount_w_returning   s    z+SuiteRequirements.sane_rowcount_w_returningc             C   s   t dd dS )zatarget platform supports INSERT with no values, i.e.
        INSERT DEFAULT VALUES or equivalent.c             S   s   | j jjp| j jjS )N)r-   r.   Zsupports_empty_insertZsupports_default_values)r/   r
   r
   r   r     s   
z1SuiteRequirements.empty_inserts.<locals>.<lambda>zempty inserts not supported)r   r   )r   r
   r
   r   empty_inserts   s    zSuiteRequirements.empty_insertsc             C   s   t  S )z.target platform supports INSERT from a SELECT.)r   r   )r   r
   r
   r   insert_from_select  s    z$SuiteRequirements.insert_from_selectc             C   s   t dd dS )z#target platform supports RETURNING.c             S   s
   | j jjS )N)r-   r.   Zimplicit_returning)r/   r
   r
   r   r     s    z-SuiteRequirements.returning.<locals>.<lambda>z)%(database)s %(does_support)s 'returning')r   r   )r   r
   r
   r   	returning  s    zSuiteRequirements.returningc             C   s   t  S )zZTarget platform supports the syntax
        "(x, y) IN ((x1, y1), (x2, y2), ...)"
        )r   r   )r   r
   r
   r   tuple_in  s    zSuiteRequirements.tuple_inc             C   s   t  S )zwtarget platform supports a SELECT statement that has
        the same name repeated more than once in the columns list.)r   r   )r   r
   r
   r   %duplicate_names_in_cursor_description  s    z7SuiteRequirements.duplicate_names_in_cursor_descriptionc             C   s   t dd dS )z[Target database must have 'denormalized', i.e.
        UPPERCASE as case insensitive names.c             S   s   | j jj S )N)r-   r.   Zrequires_name_normalize)r/   r
   r
   r   r   +  s    z6SuiteRequirements.denormalized_names.<locals>.<lambda>z,Backend does not require denormalized names.)r   r0   )r   r
   r
   r   denormalized_names%  s    z$SuiteRequirements.denormalized_namesc             C   s   t dd dS )zTtarget database must support multiple VALUES clauses in an
        INSERT statement.c             S   s   | j jj S )N)r-   r.   Zsupports_multivalues_insert)r/   r
   r
   r   r   5  s    z7SuiteRequirements.multivalues_inserts.<locals>.<lambda>z*Backend does not support multirow inserts.)r   r0   )r   r
   r
   r   multivalues_inserts/  s    z%SuiteRequirements.multivalues_insertsc             C   s   t  S )zw"target dialect implements the executioncontext.get_lastrowid()
        method without reliance on RETURNING.

        )r   r   )r   r
   r
   r   implements_get_lastrowid9  s    z*SuiteRequirements.implements_get_lastrowidc             C   s   t  S )a=  "target dialect retrieves cursor.lastrowid, or fetches
        from a database-side function after an insert() construct executes,
        within the get_lastrowid() method.

        Only dialects that "pre-execute", or need RETURNING to get last
        inserted id, would return closed/fail/skip for this.

        )r   r   )r   r
   r
   r   emulated_lastrowidA  s    
z$SuiteRequirements.emulated_lastrowidc             C   s   t  S )z^"target platform includes a 'lastrowid' accessor on the DBAPI
        cursor object.

        )r   r   )r   r
   r
   r   dbapi_lastrowidM  s    z!SuiteRequirements.dbapi_lastrowidc             C   s   t  S )z#Target database must support VIEWs.)r   r   )r   r
   r
   r   viewsU  s    zSuiteRequirements.viewsc             C   s   t  S )zXTarget database must support external schemas, and have one
        named 'test_schema'.)r   r   )r   r
   r
   r   schemas[  s    zSuiteRequirements.schemasc             C   s   t dd gdS )z0Target dialect must support server side cursors.c             S   s
   | j jjS )N)r-   r.   Zsupports_server_side_cursors)r/   r
   r
   r   r   g  s    z7SuiteRequirements.server_side_cursors.<locals>.<lambda>zno server side cursors support)r   r   )r   r
   r
   r   server_side_cursorsb  s    z%SuiteRequirements.server_side_cursorsc             C   s   t dd gdS )z'Target database must support SEQUENCEs.c             S   s
   | j jjS )N)r-   r.   supports_sequences)r/   r
   r
   r   r   p  s    z-SuiteRequirements.sequences.<locals>.<lambda>zno sequence support)r   r   )r   r
   r
   r   	sequencesk  s    zSuiteRequirements.sequencesc             C   s   t dd gdS )zgTarget database supports sequences, but also optionally
        as a means of generating new PK values.c             S   s   | j jjo| j jjS )N)r-   r.   rB   sequences_optional)r/   r
   r
   r   r   {  s   
z6SuiteRequirements.sequences_optional.<locals>.<lambda>z.no sequence support, or sequences not optional)r   r   )r   r
   r
   r   rD   t  s    z$SuiteRequirements.sequences_optionalc             C   s   t  S )N)r   r   )r   r
   r
   r   reflects_pk_names  s    z#SuiteRequirements.reflects_pk_namesc             C   s   t  S )N)r   r   )r   r
   r
   r   table_reflection  s    z"SuiteRequirements.table_reflectionc             C   s   t  S )N)r   r   )r   r
   r
   r   comment_reflection  s    z$SuiteRequirements.comment_reflectionc             C   s   | j S )ztarget database must support retrieval of the columns in a view,
        similarly to how a table is inspected.

        This does not include the full CREATE VIEW definition.

        )r?   )r   r
   r
   r   view_column_reflection  s    z(SuiteRequirements.view_column_reflectionc             C   s   | j S )zTtarget database must support inspection of the full CREATE VIEW definition.
        )r?   )r   r
   r
   r   view_reflection  s    z!SuiteRequirements.view_reflectionc             C   s   | j S )N)r@   )r   r
   r
   r   schema_reflection  s    z#SuiteRequirements.schema_reflectionc             C   s   t  S )N)r   r   )r   r
   r
   r   !primary_key_constraint_reflection  s    z3SuiteRequirements.primary_key_constraint_reflectionc             C   s   t  S )N)r   r   )r   r
   r
   r   !foreign_key_constraint_reflection  s    z3SuiteRequirements.foreign_key_constraint_reflectionc             C   s   t  S )N)r   r   )r   r
   r
   r   1foreign_key_constraint_option_reflection_ondelete  s    zCSuiteRequirements.foreign_key_constraint_option_reflection_ondeletec             C   s   t  S )N)r   r   )r   r
   r
   r   1foreign_key_constraint_option_reflection_onupdate  s    zCSuiteRequirements.foreign_key_constraint_option_reflection_onupdatec             C   s   t  S )N)r   r   )r   r
   r
   r   temp_table_reflection  s    z'SuiteRequirements.temp_table_reflectionc             C   s   t  S )z8target dialect supports listing of temporary table names)r   r   )r   r
   r
   r   temp_table_names  s    z"SuiteRequirements.temp_table_namesc             C   s   t  S )z)target database supports temporary tables)r   r   )r   r
   r
   r   temporary_tables  s    z"SuiteRequirements.temporary_tablesc             C   s   t  S )z(target database supports temporary views)r   r   )r   r
   r
   r   temporary_views  s    z!SuiteRequirements.temporary_viewsc             C   s   t  S )N)r   r   )r   r
   r
   r   index_reflection  s    z"SuiteRequirements.index_reflectionc             C   s   t  S )z>target database supports CREATE INDEX against SQL expressions.)r   r   )r   r
   r
   r   indexes_with_expressions  s    z*SuiteRequirements.indexes_with_expressionsc             C   s   t  S )z8target dialect supports reflection of unique constraints)r   r   )r   r
   r
   r   unique_constraint_reflection  s    z.SuiteRequirements.unique_constraint_reflectionc             C   s   t  S )z7target dialect supports reflection of check constraints)r   r   )r   r
   r
   r   check_constraint_reflection  s    z-SuiteRequirements.check_constraint_reflectionc             C   s   t  S )ztarget dialect raises IntegrityError when reporting an INSERT
        with a primary key violation.  (hint: it should)

        )r   r   )r   r
   r
   r   $duplicate_key_raises_integrity_error  s    z6SuiteRequirements.duplicate_key_raises_integrity_errorc             C   s   t  S )z3Target database must support VARCHAR with no length)r   r   )r   r
   r
   r   unbounded_varchar  s    z#SuiteRequirements.unbounded_varcharc             C   s   t  S )zTarget database/dialect must support Python unicode objects with
        non-ASCII characters represented, delivered as bound parameters
        as well as in result rows.

        )r   r   )r   r
   r
   r   unicode_data  s    zSuiteRequirements.unicode_datac             C   s   t  S )zRTarget driver must support some degree of non-ascii symbol
        names.
        )r   r   )r   r
   r
   r   unicode_ddl  s    zSuiteRequirements.unicode_ddlc             C   s   t  S )ztarget dialect supports rendering of a date, time, or datetime as a
        literal string, e.g. via the TypeEngine.literal_processor() method.

        )r   r   )r   r
   r
   r   datetime_literals  s    z#SuiteRequirements.datetime_literalsc             C   s   t  S )zUtarget dialect supports representation of Python
        datetime.datetime() objects.)r   r   )r   r
   r
   r   datetime  s    zSuiteRequirements.datetimec             C   s   t  S )zftarget dialect supports representation of Python
        datetime.datetime() with microsecond objects.)r   r   )r   r
   r
   r   datetime_microseconds  s    z'SuiteRequirements.datetime_microsecondsc             C   s   t  S )ztarget dialect supports representation of Python
        datetime.datetime() with microsecond objects but only
        if TIMESTAMP is used.)r   r   )r   r
   r
   r   timestamp_microseconds  s    z(SuiteRequirements.timestamp_microsecondsc             C   s   t  S )zutarget dialect supports representation of Python
        datetime.datetime() objects with historic (pre 1970) values.)r   r   )r   r
   r
   r   datetime_historic  s    z#SuiteRequirements.datetime_historicc             C   s   t  S )zQtarget dialect supports representation of Python
        datetime.date() objects.)r   r   )r   r
   r
   r   date  s    zSuiteRequirements.datec             C   s   t  S )zPtarget dialect accepts a datetime object as the target
        of a date column.)r   r   )r   r
   r
   r   date_coerces_from_datetime!  s    z,SuiteRequirements.date_coerces_from_datetimec             C   s   t  S )zutarget dialect supports representation of Python
        datetime.datetime() objects with historic (pre 1970) values.)r   r   )r   r
   r
   r   date_historic(  s    zSuiteRequirements.date_historicc             C   s   t  S )zQtarget dialect supports representation of Python
        datetime.time() objects.)r   r   )r   r
   r
   r   time/  s    zSuiteRequirements.timec             C   s   t  S )zbtarget dialect supports representation of Python
        datetime.time() with microsecond objects.)r   r   )r   r
   r
   r   time_microseconds6  s    z#SuiteRequirements.time_microsecondsc             C   s   t  S )zttarget database/driver can allow BLOB/BINARY fields to be compared
        against a bound parameter value.
        )r   r   )r   r
   r
   r   binary_comparisons=  s    z$SuiteRequirements.binary_comparisonsc             C   s   t  S )a!  target backend supports simple binary literals, e.g. an
        expression like::

            SELECT CAST('foo' AS BINARY)

        Where ``BINARY`` is the type emitted from :class:`.LargeBinary`,
        e.g. it could be ``BLOB`` or similar.

        Basically fails on Oracle.

        )r   r   )r   r
   r
   r   binary_literalsE  s    z!SuiteRequirements.binary_literalsc             C   s   t  S )z:target dialect supports 'AUTOCOMMIT' as an isolation_level)r   r   )r   r
   r
   r   
autocommitU  s    zSuiteRequirements.autocommitc             C   s   t  S )z.target platform implements a native JSON type.)r   r   )r   r
   r
   r   	json_typeZ  s    zSuiteRequirements.json_typec             C   s   | j S )zO"target platform supports numeric array indexes
        within a JSON structure)rh   )r   r
   r
   r   json_array_indexes`  s    z$SuiteRequirements.json_array_indexesc             C   s   t  S )zRtarget backend has general support for moderately high-precision
        numerics.)r   r   )r   r
   r
   r   precision_numerics_generalg  s    z,SuiteRequirements.precision_numerics_generalc             C   s   t  S )zbtarget backend supports Decimal() objects using E notation
        to represent very small values.)r   r   )r   r
   r
   r   "precision_numerics_enotation_smallm  s    z4SuiteRequirements.precision_numerics_enotation_smallc             C   s   t  S )zbtarget backend supports Decimal() objects using E notation
        to represent very large values.)r   r   )r   r
   r
   r   "precision_numerics_enotation_larges  s    z4SuiteRequirements.precision_numerics_enotation_largec             C   s   t  S )ztarget backend supports values with many digits on both sides,
        such as 319438950232418390.273596, 87673.594069654243

        )r   r   )r   r
   r
   r   *precision_numerics_many_significant_digitsy  s    z<SuiteRequirements.precision_numerics_many_significant_digitsc             C   s   t  S )a-  target backend will return a selected Decimal as a Decimal, not
        a string.

        e.g.::

            expr = decimal.Decimal("15.7563")

            value = e.scalar(
                select([literal(expr)])
            )

            assert value == expr

        See :ticket:`4036`

        )r   r   )r   r
   r
   r   implicit_decimal_binds  s    z(SuiteRequirements.implicit_decimal_bindsc             C   s   t  S )zhtarget database can select an aggregate from a subquery that's
        also using an aggregate

        )r   r   )r   r
   r
   r   nested_aggregates  s    z#SuiteRequirements.nested_aggregatesc             C   s   t  S )zbtarget database must support ON DELETE CASCADE on a self-referential
        foreign key

        )r   r   )r   r
   r
   r   recursive_fk_cascade  s    z&SuiteRequirements.recursive_fk_cascadec             C   s   t  S )zA precision numeric type will return empty significant digits,
        i.e. a value such as 10.000 will come back in Decimal form with
        the .000 maintained.)r   r   )r   r
   r
   r   -precision_numerics_retains_significant_digits  s    z?SuiteRequirements.precision_numerics_retains_significant_digitsc             C   s   t  S )ztarget backend will return native floating point numbers with at
        least seven decimal places when using the generic Float type.

        )r   r   )r   r
   r
   r   precision_generic_float_type  s    z.SuiteRequirements.precision_generic_float_typec             C   s   t  S )ztarget backend can return a floating-point number with four
        significant digits (such as 15.7563) accurately
        (i.e. without FP inaccuracies, such as 15.75629997253418).

        )r   r   )r   r
   r
   r   floats_to_four_decimals  s    z)SuiteRequirements.floats_to_four_decimalsc             C   s   t  S )ztarget backend doesn't crash when you try to select a NUMERIC
        value that has a value of NULL.

        Added to support Pyodbc bug #351.
        )r   r   )r   r
   r
   r   fetch_null_from_numeric  s    z)SuiteRequirements.fetch_null_from_numericc             C   s   t  S )zUTarget database must support an unbounded Text() "
        "type such as TEXT or CLOB)r   r   )r   r
   r
   r   	text_type  s    zSuiteRequirements.text_typec             C   s   t  S )zTtarget database can persist/return an empty string with a
        varchar.

        )r   r   )r   r
   r
   r   empty_strings_varchar  s    z'SuiteRequirements.empty_strings_varcharc             C   s   t  S )zRtarget database can persist/return an empty string with an
        unbounded text.)r   r   )r   r
   r
   r   empty_strings_text  s    z$SuiteRequirements.empty_strings_textc             C   s   t  S )zUtarget database supports use of an unbounded textual field in a
        WHERE clause.)r   r   )r   r
   r
   r   "expressions_against_unbounded_text  s    z4SuiteRequirements.expressions_against_unbounded_textc             C   s   t  S )z;target driver must support the literal statement 'select 1')r   r   )r   r
   r
   r   	selectone  s    zSuiteRequirements.selectonec             C   s   t  S )z(Target database must support savepoints.)r   r   )r   r
   r
   r   
savepoints  s    zSuiteRequirements.savepointsc             C   s   t  S )z4Target database must support two-phase transactions.)r   r   )r   r
   r
   r   two_phase_transactions  s    z(SuiteRequirements.two_phase_transactionsc             C   s   t  S )z'Target must support UPDATE..FROM syntax)r   r   )r   r
   r
   r   update_from  s    zSuiteRequirements.update_fromc             C   s   t  S )z=Target must support DELETE FROM..FROM or DELETE..USING syntax)r   r   )r   r
   r
   r   delete_from  s    zSuiteRequirements.delete_fromc             C   s   t  S )a  Target must support UPDATE (or DELETE) where the same table is
        present in a subquery in the WHERE clause.

        This is an ANSI-standard syntax that apparently MySQL can't handle,
        such as::

            UPDATE documents SET flag=1 WHERE documents.title IN
                (SELECT max(documents.title) AS title
                    FROM documents GROUP BY documents.user_id
                )

        )r   r   )r   r
   r
   r   update_where_target_in_subquery  s    z1SuiteRequirements.update_where_target_in_subqueryc             C   s   t  S )zOtarget database must use a plain percent '%' as the 'modulus'
        operator.)r   r   )r   r
   r
   r   mod_operator_as_percent_sign  s    z.SuiteRequirements.mod_operator_as_percent_signc             C   s   t  S )a  target backend supports weird identifiers with percent signs
        in them, e.g. 'some % column'.

        this is a very weird use case but often has problems because of
        DBAPIs that use python formatting.  It's not a critical use
        case either.

        )r   r   )r   r
   r
   r   percent_schema_names  s    
z&SuiteRequirements.percent_schema_namesc             C   s   t  S )a  target backend supports ORDER BY a column label within an
        expression.

        Basically this::

            select data as foo from test order by foo || 'bar'

        Lots of databases including PostgreSQL don't support this,
        so this is off by default.

        )r   r   )r   r
   r
   r   order_by_label_with_expression#  s    z0SuiteRequirements.order_by_label_with_expressionc                s    fdd}t |S )Nc                s(   y  |  dS  tk
r"   dS X d S )NFT)get_order_by_collationNotImplementedError)r/   )r   r
   r   check4  s
    
z3SuiteRequirements.order_by_collation.<locals>.check)r   r0   )r   r   r
   )r   r   order_by_collation2  s    z$SuiteRequirements.order_by_collationc             C   s
   t  d S )N)r   )r   r/   r
   r
   r   r   =  s    z(SuiteRequirements.get_order_by_collationc             C   s   t  S )zUTarget driver must support non-ASCII characters being passed at
        all.
        )r   r   )r   r
   r
   r   unicode_connections@  s    z%SuiteRequirements.unicode_connectionsc             C   s   t  S )zTarget driver must raise a DBAPI-level exception, such as
        InterfaceError, when the underlying connection has been closed
        and the execute() method is called.
        )r   r   )r   r
   r
   r   graceful_disconnectsG  s    z&SuiteRequirements.graceful_disconnectsc             C   s   t  S )z9Catchall for a large variety of MySQL on Windows failures)r   r   )r   r
   r
   r   skip_mysql_on_windowsO  s    z'SuiteRequirements.skip_mysql_on_windowsc             C   s   t dd S )a   Test environment must allow ad-hoc engine/connection creation.

        DBs that scale poorly for many connections, even when closed, i.e.
        Oracle, may use the "--low-connections" option which flags this
        requirement as not present.

        c             S   s   | j jS )N)optionsZlow_connections)r/   r
   r
   r   r   ^  s    z2SuiteRequirements.ad_hoc_engines.<locals>.<lambda>)r   r0   )r   r
   r
   r   ad_hoc_enginesT  s    	z SuiteRequirements.ad_hoc_enginesc             C   s
   t dS )Ntiming_intensive)r   requires_tag)r   r
   r
   r   r   a  s    z"SuiteRequirements.timing_intensivec             C   s
   t dS )Nmemory_intensive)r   r   )r   r
   r
   r   r   e  s    z"SuiteRequirements.memory_intensivec             C   s   t dd dS )zMark tests that use threading and mock at the same time - stability
        issues have been observed with coverage + python 3.3

        c             S   s   t jo| jjS )N)r   Zpy3kr   has_coverage)r/   r
   r
   r   r   p  s    z7SuiteRequirements.threading_with_mock.<locals>.<lambda>z%Stability issues with coverage + py3k)r   r0   )r   r
   r
   r   threading_with_mocki  s    z%SuiteRequirements.threading_with_mockc             C   s   t dd dS )Nc               S   s
   t jdkS )N)   )sysversion_infor
   r
   r
   r   r   w  s    z+SuiteRequirements.python2.<locals>.<lambda>z Python version 2.xx is required.)r   r0   )r   r
   r
   r   python2t  s    zSuiteRequirements.python2c             C   s   t dd dS )Nc               S   s
   t jdk S )N)r   )r   r   r
   r
   r
   r   r   ~  s    z+SuiteRequirements.python3.<locals>.<lambda>z Python version 3.xx is required.)r   r0   )r   r
   r
   r   python3{  s    zSuiteRequirements.python3c             C   s   t dd dS )Nc               S   s   t jS )N)r   cpythonr
   r
   r
   r   r     s    z+SuiteRequirements.cpython.<locals>.<lambda>zcPython interpreter needed)r   r   )r   r
   r
   r   r     s    zSuiteRequirements.cpythonc                s    ddl m  t fdddS )Nr   )picklec                  s   t j r jdkptjdkS )NZcPickle)r   r   )r   Zpypyr   r   r   r
   )r   r
   r   r     s   
z5SuiteRequirements.non_broken_pickle.<locals>.<lambda>z.Needs cPickle+cPython or newer Python 3 pickle)Zsqlalchemy.utilr   r   r   )r   r
   )r   r   non_broken_pickle  s    
z#SuiteRequirements.non_broken_picklec             C   s   | j S )ztarget platform must remove all cycles unconditionally when
        gc.collect() is called, as well as clean out unreferenced subclasses.

        )r   )r   r
   r
   r   predictable_gc  s    z SuiteRequirements.predictable_gcc             C   s   t dd dS )zTest should be skipped if coverage is enabled.

        This is to block tests that exercise libraries that seem to be
        sensitive to coverage, such as PostgreSQL notice logging.

        c             S   s   | j jS )N)r   r   )r/   r
   r
   r   r     s    z/SuiteRequirements.no_coverage.<locals>.<lambda>z(Issues observed when coverage is enabled)r   r0   )r   r
   r
   r   no_coverage  s    zSuiteRequirements.no_coveragec             C   s   dS )NFr
   )r   r/   r
   r
   r   _has_mysql_on_windows  s    z'SuiteRequirements._has_mysql_on_windowsc             C   s   dS )NFr
   )r   r/   r
   r
   r   _has_mysql_fully_case_sensitive  s    z1SuiteRequirements._has_mysql_fully_case_sensitivec                s   t  fddS )Nc                  s
       S )N)_has_sqliter
   )r   r
   r   r     s    z*SuiteRequirements.sqlite.<locals>.<lambda>)r   r0   )r   r
   )r   r   sqlite  s    zSuiteRequirements.sqlitec                s   t  fdddS )Nc                  s
       S )N)_has_cextensionsr
   )r   r
   r   r     s    z/SuiteRequirements.cextensions.<locals>.<lambda>zC extensions not installed)r   r0   )r   r
   )r   r   cextensions  s    zSuiteRequirements.cextensionsc             C   s2   ddl m} y|d dS  tk
r,   dS X d S )Nr   )create_enginez	sqlite://TF)
sqlalchemyr   ImportError)r   r   r
   r
   r   r     s    zSuiteRequirements._has_sqlitec             C   s.   yddl m}m} dS  tk
r(   dS X d S )Nr   )cresultproxycprocessorsTF)r   r   r   r   )r   r   r   r
   r
   r   r     s
    z"SuiteRequirements._has_cextensionsN)r   r   r	   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r1   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   rw   rx   ry   rz   r{   r|   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r
   r
   r
   r   r      s   
			

		
			
	r   )__doc__r    r   r   objectr   r   r
   r
   r
   r   <module>   s
   