]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- whitespace removal bonanza
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 2 Jan 2011 19:23:42 +0000 (14:23 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 2 Jan 2011 19:23:42 +0000 (14:23 -0500)
268 files changed:
CHANGES
README.py3k
README.unittests
doc/build/builder/builders.py
doc/build/builder/util.py
doc/build/core/connections.rst
doc/build/core/engines.rst
doc/build/core/event.rst
doc/build/core/expression_api.rst
doc/build/core/index.rst
doc/build/core/schema.rst
doc/build/core/tutorial.rst
doc/build/core/types.rst
doc/build/index.rst
doc/build/intro.rst
doc/build/orm/collections.rst
doc/build/orm/extensions/associationproxy.rst
doc/build/orm/extensions/horizontal_shard.rst
doc/build/orm/extensions/mutable.rst
doc/build/orm/index.rst
doc/build/orm/inheritance.rst
doc/build/orm/loading.rst
doc/build/orm/mapper_config.rst
doc/build/orm/relationships.rst
doc/build/orm/session.rst
doc/build/orm/tutorial.rst
doc/build/static/docs.css
doc/build/templates/genindex.mako
doc/build/templates/layout.mako
examples/adjacency_list/adjacency_list.py
examples/association/basic_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/local_session_caching.py
examples/beaker_caching/model.py
examples/custom_attributes/custom_management.py
examples/custom_attributes/listen_for_events.py
examples/dynamic_dict/dynamic_dict.py
examples/elementtree/__init__.py
examples/elementtree/optimized_al.py
examples/elementtree/pickle.py
examples/graphs/directed_graph.py
examples/inheritance/concrete.py
examples/inheritance/polymorph.py
examples/large_collection/large_collection.py
examples/nested_sets/nested_sets.py
examples/poly_assoc/poly_assoc_generic.py
examples/postgis/__init__.py
examples/postgis/postgis.py
examples/sharding/attribute_shard.py
examples/versioning/__init__.py
examples/versioning/history_meta.py
examples/versioning/test_versioning.py
examples/vertical/__init__.py
ez_setup.py
lib/sqlalchemy/__init__.py
lib/sqlalchemy/connectors/__init__.py
lib/sqlalchemy/connectors/mxodbc.py
lib/sqlalchemy/connectors/pyodbc.py
lib/sqlalchemy/connectors/zxJDBC.py
lib/sqlalchemy/dialects/access/base.py
lib/sqlalchemy/dialects/firebird/__init__.py
lib/sqlalchemy/dialects/firebird/base.py
lib/sqlalchemy/dialects/firebird/kinterbasdb.py
lib/sqlalchemy/dialects/informix/base.py
lib/sqlalchemy/dialects/informix/informixdb.py
lib/sqlalchemy/dialects/maxdb/base.py
lib/sqlalchemy/dialects/maxdb/sapdb.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/mysql/__init__.py
lib/sqlalchemy/dialects/mysql/base.py
lib/sqlalchemy/dialects/mysql/mysqldb.py
lib/sqlalchemy/dialects/mysql/oursql.py
lib/sqlalchemy/dialects/mysql/pyodbc.py
lib/sqlalchemy/dialects/oracle/base.py
lib/sqlalchemy/dialects/oracle/cx_oracle.py
lib/sqlalchemy/dialects/postgres.py
lib/sqlalchemy/dialects/postgresql/base.py
lib/sqlalchemy/dialects/postgresql/pg8000.py
lib/sqlalchemy/dialects/postgresql/psycopg2.py
lib/sqlalchemy/dialects/sqlite/base.py
lib/sqlalchemy/dialects/sqlite/pysqlite.py
lib/sqlalchemy/dialects/sybase/base.py
lib/sqlalchemy/dialects/sybase/pyodbc.py
lib/sqlalchemy/dialects/sybase/pysybase.py
lib/sqlalchemy/dialects/type_migration_guidelines.txt
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/event.py
lib/sqlalchemy/events.py
lib/sqlalchemy/exc.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/interfaces.py
lib/sqlalchemy/log.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/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/state.py
lib/sqlalchemy/orm/strategies.py
lib/sqlalchemy/orm/sync.py
lib/sqlalchemy/orm/unitofwork.py
lib/sqlalchemy/orm/util.py
lib/sqlalchemy/pool.py
lib/sqlalchemy/processors.py
lib/sqlalchemy/schema.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/types.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/topological.py
sa2to3.py
setup.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/test_events.py
test/base/test_utils.py
test/bootstrap/noseplugin.py
test/dialect/test_firebird.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/engine/_base.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/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_sqlsoup.py
test/lib/assertsql.py
test/lib/engines.py
test/lib/entities.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/_base.py
test/orm/_fixtures.py
test/orm/inheritance/test_abc_inheritance.py
test/orm/inheritance/test_basic.py
test/orm/inheritance/test_concrete.py
test/orm/inheritance/test_magazine.py
test/orm/inheritance/test_polymorph.py
test/orm/inheritance/test_polymorph2.py
test/orm/inheritance/test_query.py
test/orm/inheritance/test_single.py
test/orm/test_assorted_eager.py
test/orm/test_attributes.py
test/orm/test_backref_mutations.py
test/orm/test_cascade.py
test/orm/test_collection.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_transaction.py
test/orm/test_unitofwork.py
test/orm/test_unitofworkv2.py
test/orm/test_utils.py
test/orm/test_versioning.py
test/perf/README
test/perf/objselectspeed.py
test/perf/orm2010.py
test/perf/sessions.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
test/zblog/test_zblog.py

diff --git a/CHANGES b/CHANGES
index 2e242f78d8fb665cc0367ad3d1b3ce8aca33ac49..f8421c26ce97169dd41baeec8687e2d88f162e77 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -17,7 +17,7 @@ CHANGES
     specified.   This makes it more compatible with Postgresql's
     VARCHAR type which is similarly unbounded when no length
     specified.
-    
+
 0.6.6
 =====
 - orm
@@ -45,12 +45,12 @@ CHANGES
     or collections taken into account when deleting
     objects, despite passive_deletes remaining at 
     its default of False.  [ticket:2002]
-    
+
   - A warning is emitted when version_id_col is specified
     on an inheriting mapper when the inherited mapper
     already has one, if those column expressions are not
     the same.  [ticket:1987]
-    
+
   - "innerjoin" flag doesn't take effect along the chain
     of joinedload() joins if a previous join in that chain
     is an outer join, thus allowing primary rows without
@@ -68,13 +68,13 @@ CHANGES
   - The mapper argument "primary_key" can be passed as a 
     single column as well as a list or tuple.  [ticket:1971]
     The documentation examples that illustrated it as a 
-    scalar value have been changed to lists.  
+    scalar value have been changed to lists.
 
   - Added active_history flag to relationship()
     and column_property(), forces attribute events to
     always load the "old" value, so that it's available to
     attributes.get_history(). [ticket:1961]
-    
+
   - Query.get() will raise if the number of params
     in a composite key is too large, as well as too 
     small. [ticket:1977]
@@ -89,7 +89,7 @@ CHANGES
     and foreign_keys wasn't used - adds "foreign_keys" to
     the suggestion.  Also add "foreign_keys" to the 
     suggestion for the generic "direction" error.
-    
+
 - sql
   - Fixed operator precedence rules for multiple
     chains of a single non-associative operator.
@@ -97,7 +97,7 @@ CHANGES
     and not "x - y - z".  Also works with labels,
     i.e. "x - (y - z).label('foo')"
     [ticket:1984]
-    
+
   - The 'info' attribute of Column is copied during 
     Column.copy(), i.e. as occurs when using columns
     in declarative mixins.  [ticket:1967]
@@ -105,17 +105,17 @@ CHANGES
   - Added a bind processor for booleans which coerces
     to int, for DBAPIs such as pymssql that naively call 
     str() on values.
-    
+
 - engine
   - The "unicode warning" against non-unicode bind data
     is now raised only when the
     Unicode type is used explictly; not when 
     convert_unicode=True is used on the engine 
     or String type.
-    
+
   - Fixed memory leak in C version of Decimal result
     processor.  [ticket:1978]
-    
+
   - Implemented sequence check capability for the C 
     version of RowProxy, as well as 2.7 style 
     "collections.Sequence" registration for RowProxy.
@@ -124,11 +124,11 @@ CHANGES
   - Threadlocal engine methods rollback(), commit(),
     prepare() won't raise if no transaction is in progress;
     this was a regression introduced in 0.6.  [ticket:1998]
-    
+
 - postgresql
   - Single element tuple expressions inside an IN clause
     parenthesize correctly, also from [ticket:1984]
-    
+
   - Ensured every numeric, float, int code, scalar + array,
     are recognized by psycopg2 and pg8000's "numeric" 
     base type. [ticket:1955]
@@ -141,7 +141,7 @@ CHANGES
   - Fixed bug whereby KeyError would occur with non-ENUM 
     supported PG versions after a pool dispose+recreate
     would occur, [ticket:1989]
-    
+
 - mysql
   - Fixed error handling for Jython + zxjdbc, such that 
     has_table() property works again.  Regression from
@@ -172,7 +172,7 @@ CHANGES
     this character.  cx_oracle 5.0.3 or greater is also required
     when using a non-period-decimal-point NLS_LANG setting.
     [ticket:1953].
-    
+
 - declarative
   - An error is raised if __table_args__ is not in tuple
     or dict format, and is not None.  [ticket:1972]
@@ -192,11 +192,11 @@ CHANGES
 - examples
   - The versioning example now supports detection of changes
     in an associated relationship().
-    
+
 0.6.5
 =====
 - orm
-  - Added a new "lazyload" option "immediateload".  
+  - Added a new "lazyload" option "immediateload".
     Issues the usual "lazy" load operation automatically
     as the object is populated.   The use case
     here is when loading objects to be placed in
@@ -204,7 +204,7 @@ CHANGES
     the session isn't available, and straight 'select'
     loading, not 'joined' or 'subquery', is desired.
     [ticket:1914]
-  
+
   - New Query methods: query.label(name), query.as_scalar(),
     return the query's statement as a scalar subquery
     with /without label [ticket:1920];
@@ -213,7 +213,7 @@ CHANGES
     Roughly equivalent to a generative form of query.values()
     which accepts mapped entities as well as column 
     expressions.
-    
+
   - Fixed recursion bug which could occur when moving
     an object from one reference to another, with 
     backrefs involved, where the initiating parent
@@ -223,11 +223,11 @@ CHANGES
   - Fixed a regression in 0.6.4 which occurred if you 
     passed an empty list to "include_properties" on 
     mapper() [ticket:1918]
-  
+
   - Fixed labeling bug in Query whereby the NamedTuple
     would mis-apply labels if any of the column
     expressions were un-labeled.
-    
+
   - Patched a case where query.join() would adapt the
     right side to the right side of the left's join
     inappropriately [ticket:1925]
@@ -238,7 +238,7 @@ CHANGES
     a mapped entity and not a plain selectable, 
     as the default "left" side, not the first entity 
     in the Query object's list of entities.
-    
+
   - The exception raised by Session when it is used
     subsequent to a subtransaction rollback (which is what
     happens when a flush fails in autocommit=False mode) has
@@ -264,7 +264,7 @@ CHANGES
     expiration would fail if the column expression key was
     a class attribute with a different keyname as the 
     actual column name.  [ticket:1935]
-    
+
   - Added an assertion during flush which ensures
     that no NULL-holding identity keys were generated
     on "newly persistent" objects.
@@ -281,7 +281,7 @@ CHANGES
     is not triggered on these loads when the attributes are
     determined and the "committed" state may not be 
     available.  [ticket:1910]
-    
+
   - A new flag on relationship(), load_on_pending, allows
     the lazy loader to fire off on pending objects without a
     flush taking place, as well as a transient object that's
@@ -290,7 +290,7 @@ CHANGES
     object is loaded, so backrefs aren't available until
     after a flush. The flag is only intended for very
     specific use cases.
-  
+
   - Another new flag on relationship(), cascade_backrefs,
     disables the "save-update" cascade when the event was
     initiated on the "reverse" side of a bidirectional 
@@ -299,7 +299,7 @@ CHANGES
     it getting sucked into the child object's session,
     while still allowing the forward collection to 
     cascade.   We *might* default this to False in 0.7.
-      
+
   - Slight improvement to the behavior of
     "passive_updates=False" when placed only on the
     many-to-one side of a relationship; documentation has
@@ -309,13 +309,13 @@ CHANGES
   - Placing passive_deletes=True on a many-to-one emits
     a warning, since you probably intended to put it on
     the one-to-many side.
-  
+
   - Fixed bug that would prevent "subqueryload" from
     working correctly with single table inheritance 
     for a relationship from a subclass - the "where 
     type in (x, y, z)" only gets placed on the inside,
     instead of repeatedly.
-    
+
   - When using from_self() with single table inheritance,
     the "where type in (x, y, z)" is placed on the outside
     of the query only, instead of repeatedly.   May make
@@ -328,12 +328,12 @@ CHANGES
   - reworked the internals of mapper.cascade_iterator() to
     cut down method calls by about 9% in some circumstances.
     [ticket:1932]
-    
+
 - sql
    - Fixed bug in TypeDecorator whereby the dialect-specific
      type was getting pulled in to generate the DDL for a 
      given type, which didn't always return the correct result.
-     
+
    - TypeDecorator can now have a fully constructed type
      specified as its "impl", in addition to a type class.
 
@@ -347,16 +347,16 @@ CHANGES
 
    - TypeDecorator.load_dialect_impl() returns "self.impl" by
      default, i.e. not the dialect implementation type of 
-     "self.impl".   This to support compilation correctly.  
+     "self.impl".   This to support compilation correctly.
      Behavior can be user-overridden in exactly the same way 
      as before to the same effect.
 
-   - Added type_coerce(expr, type_) expression element.  
+   - Added type_coerce(expr, type_) expression element.
      Treats the given expression as the given type when evaluating
      expressions and processing result rows, but does not 
      affect the generation of SQL, other than an anonymous
      label.
-     
+
    - Table.tometadata() now copies Index objects associated
      with the Table as well.
 
@@ -379,7 +379,7 @@ CHANGES
    - Fixed recursion overflow which could occur when operating
      with two expressions both of type "NullType", but
      not the singleton NULLTYPE instance. [ticket:1907]
-     
+
 - declarative
    - @classproperty (soon/now @declared_attr) takes effect for 
      __mapper_args__, __table_args__, __tablename__ on 
@@ -401,27 +401,27 @@ CHANGES
    - A mixin can now specify a column that overrides 
      a column of the same name associated with a superclass.
      Thanks to Oystein Haaland.
-     
+
 - engine
-   
+
    - Fixed a regression in 0.6.4 whereby the change that
      allowed cursor errors to be raised consistently broke
      the result.lastrowid accessor.   Test coverage has
      been added for result.lastrowid.   Note that lastrowid
      is only supported by Pysqlite and some MySQL drivers,
      so isn't super-useful in the general case.
-   
+
    - the logging message emitted by the engine when
      a connection is first used is now "BEGIN (implicit)" 
      to emphasize that DBAPI has no explicit begin().
-   
+
    - added "views=True" option to metadata.reflect(), 
      will add the list of available views to those
      being reflected.  [ticket:1936]
 
    - engine_from_config() now accepts 'debug' for 
      'echo', 'echo_pool', 'force' for 'convert_unicode',
-     boolean values for 'use_native_unicode'.  
+     boolean values for 'use_native_unicode'.
      [ticket:1899]
 
 - postgresql
@@ -443,11 +443,11 @@ CHANGES
      Oracle.  Previously, the flag would be forced
      to False if server version info was < 10.
      [ticket:1878]
-     
+
 - mssql
    - Fixed reflection bug which did not properly handle
      reflection of unknown types.  [ticket:1946]
-    
+
    - Fixed bug where aliasing of tables with "schema" would
      fail to compile properly.  [ticket:1943]
 
@@ -456,10 +456,10 @@ CHANGES
      (spaces, embedded commas, etc.) can be reflected.
      Note that reflection of indexes requires SQL 
      Server 2005 or greater.  [ticket:1770]
-     
+
    - mssql+pymssql dialect now honors the "port" portion
      of the URL instead of discarding it.  [ticket:1952]
-     
+
 - informix
    - *Major* cleanup / modernization of the Informix 
      dialect for 0.6, courtesy Florian Apolloner. 
@@ -473,13 +473,13 @@ CHANGES
      --with-coverage option to turn on coverage before
      SQLAlchemy modules are imported, allowing coverage
      to work correctly.
-      
+
 - misc
    - CircularDependencyError now has .cycles and .edges
      members, which are the set of elements involved in
-     one or more cycles, and the set of edges as 2-tuples.  
+     one or more cycles, and the set of edges as 2-tuples.
      [ticket:1890]
-     
+
 0.6.4
 =====
 - orm
@@ -498,19 +498,19 @@ CHANGES
     iterable.   This because asyncrhonous gc 
     can remove items via the gc thread at any time.
     [ticket:1891]
-    
+
   - The Session class is now present in sqlalchemy.orm.*.
     We're moving away from the usage of create_session(),
     which has non-standard defaults, for those situations
     where a one-step Session constructor is desired. Most
     users should stick with sessionmaker() for general use,
     however.
-  
+
   - query.with_parent() now accepts transient objects
     and will use the non-persistent values of their pk/fk
-    attributes in order to formulate the criterion.  
+    attributes in order to formulate the criterion.
     Docs are also clarified as to the purpose of with_parent().
-    
+
   - The include_properties and exclude_properties arguments
     to mapper() now accept Column objects as members in 
     addition to strings.  This so that same-named Column
@@ -525,9 +525,9 @@ CHANGES
     In 0.7 this warning will be an exception.   Note that
     this warning is not emitted when the combination occurs
     as a result of inheritance, so that attributes
-    still allow being overridden naturally.  
+    still allow being overridden naturally.
     [ticket:1896].  In 0.7 this will be improved further.
-    
+
   - The primary_key argument to mapper() can now specify
     a series of columns that are only a subset of 
     the calculated "primary key" columns of the mapped 
@@ -537,7 +537,7 @@ CHANGES
     in the selectable that are actually marked as 
     "primary_key", such as a join against two 
     tables on their primary key columns [ticket:1896].
-    
+
   - An object that's been deleted now gets a flag
     'deleted', which prohibits the object from
     being re-add()ed to the session, as previously
@@ -548,7 +548,7 @@ CHANGES
 
   - make_transient() can be safely called on an
     already transient instance.
-    
+
   - a warning is emitted in mapper() if the polymorphic_on
     column is not present either in direct or derived
     form in the mapped selectable or in the 
@@ -580,7 +580,7 @@ CHANGES
     the foreign keys to be elsewhere in any case.
     A warning is now emitted instead of an error, 
     and the mapping succeeds. [ticket:1877]
-    
+
   - Moving an o2m object from one collection to
     another, or vice versa changing the referenced
     object by an m2o, where the foreign key is also a
@@ -596,7 +596,7 @@ CHANGES
     at the "old", assuming passive_updates=True,
     unless we know it was a PK switch that
     triggered the change. [ticket:1856]
-    
+
   - The value of version_id_col can be changed 
     manually, and this will result in an UPDATE
     of the row.  Versioned UPDATEs and DELETEs
@@ -626,7 +626,7 @@ CHANGES
     expressions are enforced - lists of strings
     are explicitly disallowed since this is a
     very common error
-    
+
   - Dynamic attributes don't support collection 
     population - added an assertion for when
     set_committed_value() is called, as well as
@@ -658,14 +658,14 @@ CHANGES
   - the versioning example works correctly now
     if versioning on a col that was formerly 
     NULL.
-    
+
 - sql
   - Calling execute() on an alias() construct is pending
     deprecation for 0.7, as it is not itself an
     "executable" construct. It currently "proxies" its
     inner element and is conditionally "executable" but
     this is not the kind of ambiguity we like these days.
-    
+
   - The execute() and scalar() methods of ClauseElement
     are now moved appropriately to the Executable
     subclass. ClauseElement.execute()/ scalar() are still
@@ -673,12 +673,12 @@ CHANGES
     these would always raise an error anyway if you were
     not an Executable (unless you were an alias(), see
     previous note).
-    
+
   - Added basic math expression coercion for 
     Numeric->Integer,
     so that resulting type is Numeric regardless
     of the direction of the expression.
-    
+
   - Changed the scheme used to generate truncated
     "auto" index names when using the "index=True"
     flag on Column.   The truncation only takes
@@ -768,7 +768,7 @@ CHANGES
     upon the base "SET SESSION ISOLATION" command,
     as psycopg2 resets the isolation level on each new 
     transaction otherwise.
-    
+
 - mssql
   - Fixed "default schema" query to work with
     pymssql backend.
@@ -776,7 +776,7 @@ CHANGES
 - firebird
   - Fixed bug whereby a column default would fail to 
     reflect if the "default" keyword were lower case.
-    
+
 - oracle
   - Added ROWID type to the Oracle dialect, for those
     cases where an explicit CAST might be needed.
@@ -813,7 +813,7 @@ CHANGES
     "SQLAlchemy ORM" sections, mapper/relationship docs
     have been broken out. Lots of sections rewritten
     and/or reorganized.
-    
+
 - examples
   - The beaker_caching example has been reorgnized
     such that the Session, cache manager, 
@@ -826,7 +826,7 @@ CHANGES
     when copying columns, so that the versioning 
     table handles multiple rows with repeating values.
     [ticket:1887]
-    
+
 0.6.3
 =====
 - orm
@@ -843,7 +843,7 @@ CHANGES
     themselves + a selectable (i.e. from_self(), 
     union(), etc.), so that join() and such have the 
     correct state to work from.  [ticket:1853]
-    
+
   - Fixed bug where Query.join() would fail if
     querying a non-ORM column then joining without
     an on clause when a FROM clause is already
@@ -856,13 +856,13 @@ CHANGES
     but the subclass is not.  Any attempts to access
     cls._sa_class_manager.mapper now raise 
     UnmappedClassError().  [ticket:1142]
-    
+
   - Added "column_descriptions" accessor to Query,
     returns a list of dictionaries containing
     naming/typing information about the entities
     the Query will return.  Can be helpful for 
     building GUIs on top of ORM queries.
-    
+
 - mysql
 
   - The _extract_error_code() method now works 
@@ -883,7 +883,7 @@ CHANGES
     come back as ints without SQLA type 
     objects being involved and without needless
     conversion to Decimal first.
-    
+
     Unfortunately, some exotic subquery cases 
     can even see different types between 
     individual result rows, so the Numeric 
@@ -900,13 +900,13 @@ CHANGES
     form query.join(target, clause_expression), 
     i.e. missing the tuple, and raise an informative
     error message that this is the wrong calling form.
-    
+
   - Fixed bug regarding flushes on self-referential 
     bi-directional many-to-many relationships, where
     two objects made to mutually reference each other
     in one flush would fail to insert a row for both
     sides.  Regression from 0.5. [ticket:1824]
-  
+
   - the post_update feature of relationship() has been
     reworked architecturally to integrate more closely
     with the new 0.6 unit of work.  The motivation 
@@ -917,13 +917,13 @@ CHANGES
     statement per column per row.   Multiple row
     updates are also batched into executemany()s as 
     possible, while maintaining consistent row ordering.
-    
+
   - Query.statement, Query.subquery(), etc. now transfer
     the values of bind parameters, i.e. those specified
     by query.params(), into the resulting SQL expression.
     Previously the values would not be transferred
     and bind parameters would come out as None.
-    
+
   - Subquery-eager-loading now works with Query objects
     which include params(), as well as get() Queries.
 
@@ -954,12 +954,12 @@ CHANGES
 
   - The make_transient() function is now in the generated
     documentation.
-    
+
   - make_transient() removes all "loader" callables from
     the state being made transient, removing any
     "expired" state - all unloaded attributes reset back
     to undefined, None/empty on access.
-    
+
 - sql
   - The warning emitted by the Unicode and String types
     with convert_unicode=True no longer embeds the actual
@@ -972,11 +972,11 @@ CHANGES
   - Fixed bug that would prevent overridden clause
     compilation from working for "annotated" expression
     elements, which are often generated by the ORM.
-    
+
   - The argument to "ESCAPE" of a LIKE operator or similar
     is passed through render_literal_value(), which may 
     implement escaping of backslashes.  [ticket:1400]
-    
+
   - Fixed bug in Enum type which blew away native_enum
     flag when used with TypeDecorators or other adaption
     scenarios.
@@ -984,7 +984,7 @@ CHANGES
   - Inspector hits bind.connect() when invoked to ensure
     initialize has been called.  the internal name ".conn"
     is changed to ".bind", since that's what it is.
-    
+
   - Modified the internals of "column annotation" such that
     a custom Column subclass can safely override
     _constructor to return Column, for the purposes of 
@@ -998,30 +998,30 @@ CHANGES
 - postgresql
   - render_literal_value() is overridden which escapes
     backslashes, currently applies to the ESCAPE clause
-    of LIKE and similar expressions.   
+    of LIKE and similar expressions.
     Ultimately this will have to detect the value of 
-    "standard_conforming_strings" for full behavior.  
+    "standard_conforming_strings" for full behavior.
     [ticket:1400]
 
   - Won't generate "CREATE TYPE" / "DROP TYPE" if
     using types.Enum on a PG version prior to 8.3 - 
     the supports_native_enum flag is fully
     honored.  [ticket:1836]
-    
+
 - mysql
   - MySQL dialect doesn't emit CAST() for MySQL version 
     detected < 4.0.2.  This allows the unicode
     check on connect to proceed. [ticket:1826]
 
   - MySQL dialect now detects NO_BACKSLASH_ESCAPES sql
-    mode, in addition to ANSI_QUOTES.  
-    
+    mode, in addition to ANSI_QUOTES.
+
   - render_literal_value() is overridden which escapes
     backslashes, currently applies to the ESCAPE clause
     of LIKE and similar expressions.   This behavior
     is derived from detecting the value of 
     NO_BACKSLASH_ESCAPES.  [ticket:1400]
-    
+
 - oracle:
   - Fixed ora-8 compatibility flags such that they
     don't cache a stale value from before the first
@@ -1045,7 +1045,7 @@ CHANGES
     which suggests checking that the FreeTDS version 
     configuration is using 7.0 or 8.0, not 4.2.
     [ticket:1825]
-    
+
 - firebird
   - Fixed incorrect signature in do_execute(), error 
     introduced in 0.6.1. [ticket:1823]
@@ -1053,7 +1053,7 @@ CHANGES
   - Firebird dialect adds CHAR, VARCHAR types which
     accept a "charset" flag, to support Firebird
     "CHARACTER SET" clause.  [ticket:1813]
-  
+
 - declarative
    - Added support for @classproperty to provide 
      any kind of schema/mapping construct from a 
@@ -1063,7 +1063,7 @@ CHANGES
      An error is raised if any MapperProperty subclass
      is specified on a mixin without using @classproperty.
      [ticket:1751] [ticket:1796] [ticket:1805]
-     
+
    - a mixin class can now define a column that matches
      one which is present on a __table__ defined on a 
      subclass.  It cannot, however, define one that is 
@@ -1077,7 +1077,7 @@ CHANGES
     user-defined compiler is specific to certain 
     backends and compilation for a different backend
     is invoked. [ticket:1838]
-    
+
 - documentation
   - Added documentation for the Inspector. [ticket:1820]
 
@@ -1085,18 +1085,18 @@ CHANGES
     decorators so that Sphinx documentation picks up 
     these attributes and methods, such as 
     ResultProxy.inserted_primary_key. [ticket:1830]
-    
-    
+
+
 0.6.1
 =====
 - orm
   - Fixed regression introduced in 0.6.0 involving improper
     history accounting on mutable attributes.  [ticket:1782]
-  
+
   - Fixed regression introduced in 0.6.0 unit of work refactor
     that broke updates for bi-directional relationship()
     with post_update=True. [ticket:1807]
-    
+
   - session.merge() will not expire attributes on the returned
     instance if that instance is "pending".  [ticket:1789]
 
@@ -1117,7 +1117,7 @@ CHANGES
     the related Engine.  The cache is an LRUCache for the
     rare case that a mapper receives an extremely
     high number of different column patterns as UPDATEs.
-    
+
 - sql
   - expr.in_() now accepts a text() construct as the argument.
     Grouping parenthesis are added automatically, i.e. usage
@@ -1128,7 +1128,7 @@ CHANGES
     will coerce a "basestring" on the right side into a 
     _Binary as well so that required DBAPI processing 
     takes place.
-    
+
   - Added table.add_is_dependent_on(othertable), allows manual
     placement of dependency rules between two Table objects
     for use within create_all(), drop_all(), sorted_tables.
@@ -1137,7 +1137,7 @@ CHANGES
   - Fixed bug that prevented implicit RETURNING from functioning
     properly with composite primary key that contained zeroes.
     [ticket:1778]
-  
+
   - Fixed errant space character when generating ADD CONSTRAINT
     for a named UNIQUE constraint.
 
@@ -1162,11 +1162,11 @@ CHANGES
 
   - Pool classes will reuse the same "pool_logging_name" setting
     after a dispose() occurs.
-    
+
   - Engine gains an "execution_options" argument and 
     update_execution_options() method, which will apply to 
     all connections generated by this engine.
-    
+
 - mysql
   - func.sysdate() emits "SYSDATE()", i.e. with the ending
     parenthesis, on MySQL.  [ticket:1794]
@@ -1175,7 +1175,7 @@ CHANGES
   - Fixed concatenation of constraints when "PRIMARY KEY" 
     constraint gets moved to column level due to SQLite
     AUTOINCREMENT keyword being rendered.  [ticket:1812]
-    
+
 - oracle
   - Added a check for cx_oracle versions lower than version 5,
     in which case the incompatible "output type handler" won't 
@@ -1191,7 +1191,7 @@ CHANGES
     "native unicode" check doesn't fail, cx_oracle 
     "native unicode" mode is disabled, VARCHAR() is emitted 
     with bytes count instead of char count. [ticket:1808]
-    
+
   - oracle_xe 5 doesn't accept a Python unicode object in 
     its connect string in normal Python 2.x mode - so we coerce
     to str() directly.  non-ascii characters aren't supported
@@ -1204,12 +1204,12 @@ CHANGES
     or with subqueries, so its still not very usable, but at
     least SQLA gets the SQL past the Oracle parser.
     [ticket:1815]
-    
+
 - firebird
   - Added a label to the query used within has_table() and 
     has_sequence() to work with older versions of Firebird
     that don't provide labels for result columns. [ticket:1521]
-    
+
   - Added integer coercion to the "type_conv" attribute when 
     passed via query string, so that it is properly interpreted
     by Kinterbasdb. [ticket:1779]
@@ -1264,7 +1264,7 @@ CHANGES
     would cause a version check to occur.  Since the instance
     is first expired, refresh() always upgrades the object
     to the most recent version.
-    
+
   - The 'refresh-expire' cascade, when reaching a pending object,
     will expunge the object if the cascade also includes
     "delete-orphan", or will simply detach it otherwise.
@@ -1277,10 +1277,10 @@ CHANGES
   - The ORM will set the docstring of all generated descriptors
     to None by default.  This can be overridden using 'doc'
     (or if using Sphinx, attribute docstrings work too).
-    
+
   - Added kw argument 'doc' to all mapper property callables 
     as well as Column().  Will assemble the string 'doc' as 
-    the '__doc__' attribute on the descriptor.  
+    the '__doc__' attribute on the descriptor.
 
   - Usage of version_id_col on a backend that supports 
     cursor.rowcount for execute() but not executemany() now works
@@ -1294,12 +1294,12 @@ CHANGES
     objects of all the same class, thereby avoiding redundant
     compilation per individual INSERT/UPDATE within an 
     individual flush() call.
-    
+
   - internal getattr(), setattr(), getcommitted() methods
     on ColumnProperty, CompositeProperty, RelationshipProperty
     have been underscored (i.e. are private), signature has 
     changed.
-    
+
 - engines
   - The C extension now also works with DBAPIs which use custom
     sequences as row (and not only tuples). [ticket:1757]
@@ -1315,14 +1315,14 @@ CHANGES
   - somejoin.select(fold_equivalents=True) is no longer 
     deprecated, and will eventually be rolled into a more 
     comprehensive version of the feature for [ticket:1729].
-    
+
   - the Numeric type raises an *enormous* warning when expected
     to convert floats to Decimal from a DBAPI that returns floats.
     This includes SQLite, Sybase, MS-SQL. [ticket:1759]
 
   - Fixed an error in expression typing which caused an endless
     loop for expressions with two NULL types.
-  
+
   - Fixed bug in execution_options() feature whereby the existing
     Transaction and other state information from the parent 
     connection would not be propagated to the sub-connection.
@@ -1335,7 +1335,7 @@ CHANGES
     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.
-  
+
   - Added get_pk_constraint() to reflection.Inspector, similar
     to get_primary_keys() except returns a dict that includes the
     name of the constraint, for supported backends (PG so far).
@@ -1343,13 +1343,13 @@ CHANGES
 
   - Table.create() and Table.drop() no longer apply metadata-
     level create/drop events.  [ticket:1771]
-    
+
 - ext
   - the compiler extension now allows @compiles decorators
     on base classes that extend to child classes, @compiles
     decorators on child classes that aren't broken by a 
     @compiles decorator on the base class.
-   
+
   - Declarative will raise an informative error message
     if a non-mapped class attribute is referenced in the
     string-based relationship() arguments.
@@ -1363,7 +1363,7 @@ CHANGES
     SERIAL columns correctly, after the name of of the sequence
     has been changed.  Thanks to Kumar McMillan for the patch.
     [ticket:1071]
-    
+
   - Repaired missing import in psycopg2._PGNumeric type when 
     unknown numeric is received.
 
@@ -1373,7 +1373,7 @@ CHANGES
 
   - Postgresql reflects the name of primary key constraints,
     if one exists.  [ticket:1769]
-        
+
 - oracle
   - Now using cx_oracle output converters so that the
     DBAPI returns natively the kinds of values we prefer:
@@ -1395,12 +1395,12 @@ CHANGES
      call is slightly expensive however so it can be disabled.
      To re-enable on a per-execution basis, the 
      'enable_rowcount=True' execution option may be used.
-     
+
 - examples
   - Updated attribute_shard.py example to use a more robust
     method of searching a Query for binary expressions which
     compare columns against literal values.
-    
+
 0.6beta3
 ========
 
@@ -1423,7 +1423,7 @@ CHANGES
     loading available, the new names for eagerload() and 
     eagerload_all() are joinedload() and joinedload_all().  The 
     old names will remain as synonyms for the foreseeable future.
-    
+
   - The "lazy" flag on the relationship() function now accepts 
     a string argument for all kinds of loading: "select", "joined",
     "subquery", "noload" and "dynamic", where the default is now
@@ -1435,7 +1435,7 @@ CHANGES
     directly down to select().with_hint() and also accepts
     entities as well as tables and aliases.  See with_hint() in the 
     SQL section below. [ticket:921]
-    
+
   - Fixed bug in Query whereby calling q.join(prop).from_self(...).
     join(prop) would fail to render the second join outside the
     subquery, when joining on the same criterion as was on the 
@@ -1445,7 +1445,7 @@ CHANGES
     would fail if the underlying table (but not the actual alias) 
     were referenced inside the subquery generated by 
     q.from_self() or q.select_from().
-    
+
   - Fixed bug which affected all eagerload() and similar options 
     such that "remote" eager loads, i.e. eagerloads off of a lazy
     load such as query(A).options(eagerload(A.b, B.c))
@@ -1463,13 +1463,13 @@ CHANGES
     carefully that "Cls" is compatible with the current joinpoint,
     and act the same way as Query.join("propname", from_joinpoint=True)
     in that regard.
-    
+
 - sql
    - Added with_hint() method to select() construct.  Specify
      a table/alias, hint text, and optional dialect name, and
      "hints" will be rendered in the appropriate place in the 
      statement.  Works for Oracle, Sybase, MySQL.  [ticket:921]
-     
+
    - Fixed bug introduced in 0.6beta2 where column labels would 
      render inside of column expressions already assigned a label.
      [ticket:1747]
@@ -1490,7 +1490,7 @@ CHANGES
      when reflecting - TINYINT(1) is returned.  Use Boolean/
      BOOLEAN in table definition to get boolean conversion
      behavior.  [ticket:1752]
-     
+
 - oracle
    - The Oracle dialect will issue VARCHAR type definitions
      using character counts, i.e. VARCHAR2(50 CHAR), so that
@@ -1510,7 +1510,7 @@ CHANGES
      __tablename__, __table_args__, etc. now works if
      the method references attributes on the ultimate 
      subclass. [ticket:1749]
-    
+
    - relationships and columns with foreign keys aren't 
      allowed on declarative mixins, sorry.  [ticket:1751]
 
@@ -1518,7 +1518,7 @@ CHANGES
     - The sqlalchemy.orm.shard module now becomes an extension,
       sqlalchemy.ext.horizontal_shard.   The old import 
       works with a deprecation warning.
-      
+
 0.6beta2
 ========
 
@@ -1527,7 +1527,7 @@ CHANGES
     now that Distribute runs on Py3k.   distribute_setup.py
     is now included.  See README.py3k for Python 3 installation/
     testing instructions.
-    
+
 - orm
   - The official name for the relation() function is now
     relationship(), to eliminate confusion over the relational
@@ -1538,9 +1538,9 @@ CHANGES
     callable that, given the current value of the "version_id_col",
     returns the next version number.  Can be used for alternate
     versioning schemes such as uuid, timestamps.  [ticket:1692]
-  
+
   - added "lockmode" kw argument to Session.refresh(), will
-    pass through the string value to Query the same as  
+    pass through the string value to Query the same as
     in with_lockmode(), will also do version check for a 
     version_id_col-enabled mapping.
 
@@ -1562,11 +1562,11 @@ CHANGES
 
   - Fixed bug in session.merge() which prevented dict-like
     collections from merging.
-    
+
   - session.merge() works with relations that specifically
     don't include "merge" in their cascade options - the target
     is ignored completely.
-    
+
   - session.merge() will not expire existing scalar attributes
     on an existing target if the target has a value for that
     attribute, even if the incoming merged doesn't have
@@ -1580,7 +1580,7 @@ CHANGES
     it also is implemented within merge() such that a SELECT
     won't be issued for an incoming instance with partially
     NULL primary key if the flag is False.  [ticket:1680]
-  
+
   - Fixed bug in 0.6-reworked "many-to-one" optimizations
     such that a many-to-one that is against a non-primary key
     column on the remote table (i.e. foreign key against a 
@@ -1589,11 +1589,11 @@ CHANGES
     we will need it for proper history/backref accounting,
     and we can't pull from the local identity map on a 
     non-primary key column. [ticket:1737]
-    
+
   - fixed internal error which would occur if calling has()
     or similar complex expression on a single-table inheritance
     relation(). [ticket:1731]
-    
+
   - query.one() no longer applies LIMIT to the query, this to
     ensure that it fully counts all object identities present
     in the result, even in the case where joins may conceal
@@ -1604,15 +1604,15 @@ CHANGES
 
   - query.get() now returns None if queried for an identifier
     that is present in the identity map with a different class 
-    than the one requested, i.e. when using polymorphic loading.  
+    than the one requested, i.e. when using polymorphic loading.
     [ticket:1727]
-    
+
   - A major fix in query.join(), when the "on" clause is an
     attribute of an aliased() construct, but there is already
     an existing join made out to a compatible target, query properly
     joins to the right aliased() construct instead of sticking
     onto the right side of the existing join.  [ticket:1706]
-    
+
   - Slight improvement to the fix for [ticket:1362] to not issue 
     needless updates of the primary key column during a so-called
     "row switch" operation, i.e. add + delete of two objects
@@ -1622,13 +1622,13 @@ CHANGES
     attribute load or refresh action fails due to object
     being detached from any Session.   UnboundExecutionError
     is specific to engines bound to sessions and statements.
-    
+
   - Query called in the context of an expression will render
     disambiguating labels in all cases.    Note that this does
     not apply to the existing .statement and .subquery()
     accessor/method, which still honors the .with_labels()
-    setting that defaults to False.  
-     
+    setting that defaults to False.
+
   - Query.union() retains disambiguating labels within the
     returned statement, thus avoiding various SQL composition
     errors which can result from column name conflicts.
@@ -1654,7 +1654,7 @@ CHANGES
     query.select_from(), query.with_polymorphic(), or
     query.from_statement() raises an exception now instead of 
     silently dropping those criterion. [ticket:1736]
-    
+
   - query.scalar() now raises an exception if more than one 
     row is returned.  All other behavior remains the same.
     [ticket:1735]
@@ -1662,7 +1662,7 @@ CHANGES
   - Fixed bug which caused "row switch" logic, that is an 
     INSERT and DELETE replaced by an UPDATE, to fail when 
     version_id_col was in use. [ticket:1692]
-    
+
 - sql
   - join() will now simulate a NATURAL JOIN by default.  Meaning,
     if the left side is a join, it will attempt to join the right
@@ -1670,7 +1670,7 @@ CHANGES
     any exceptions about ambiguous join conditions if successful
     even if there are further join targets across the rest of
     the left.  [ticket:1714]
-    
+
   - The most common result processors conversion function were
     moved to the new "processors" module.  Dialect authors are
     encouraged to use those functions whenever they correspond
@@ -1696,7 +1696,7 @@ CHANGES
     Dialects can also expand upon the areas where binds are not 
     accepted, such as within argument lists of functions 
     (which don't work on MS-SQL when native SQL binding is used).
-    
+
   - Added "unicode_errors" parameter to String, Unicode, etc.
     Behaves like the 'errors' keyword argument to
     the standard library's string.decode() functions.   This flag
@@ -1711,19 +1711,19 @@ CHANGES
     in the first place (i.e. MySQL. *not* PG, Sqlite, etc.)
 
   - Added math negation operator support, -x.
-  
+
   - FunctionElement subclasses are now directly executable the
     same way any func.foo() construct is, with automatic 
     SELECT being applied when passed to execute().
-    
+
   - The "type" and "bind" keyword arguments of a func.foo() 
     construct are now local to "func." constructs and are 
     not part of the FunctionElement base class, allowing 
     a "type" to be handled in a custom constructor or 
     class-level variable.
-    
+
   - Restored the keys() method to ResultProxy.
-  
+
   - The type/expression system now does a more complete job
     of determining the return type from an expression
     as well as the adaptation of the Python operator into 
@@ -1766,7 +1766,7 @@ CHANGES
   - Column() requires a type if it has no foreign keys (this is 
     not new).  An error is now raised if a Column() has no type
     and no foreign keys.  [ticket:1705]
-    
+
   - the "scale" argument of the Numeric() type is honored when 
     coercing a returned floating point value into a string 
     on its way to Decimal - this allows accuracy to function
@@ -1775,7 +1775,7 @@ CHANGES
   - the copy() method of Column now copies over uninitialized
     "on table attach" events.  Helps with the new declarative
     "mixin" capability.
-    
+
 - engines
   - Added an optional C extension to speed up the sql layer by
     reimplementing RowProxy and the most common result processors.
@@ -1790,7 +1790,7 @@ CHANGES
     info from the cursor before commit() is called on the 
     DBAPI connection in an "autocommit" scenario.  This helps 
     mxodbc with rowcount and is probably a good idea overall.
-    
+
   - Opened up logging a bit such that isEnabledFor() is called 
     more often, so that changes to the log level for engine/pool
     will be reflected on next connect.   This adds a small 
@@ -1798,7 +1798,7 @@ CHANGES
     life a lot easier for all those situations when logging 
     just happens to be configured after create_engine() is called.
     [ticket:1719]
-    
+
   - The assert_unicode flag is deprecated.  SQLAlchemy will raise
     a warning in all cases where it is asked to encode a non-unicode
     Python string, as well as when a Unicode or UnicodeType type
@@ -1823,19 +1823,19 @@ CHANGES
     filters down to that of Pool.   Issues the given string name
     within the "name" field of logging messages instead of the default
     hex identifier string.  [ticket:1555]
-    
+
   - The visit_pool() method of Dialect is removed, and replaced with
     connect().  This method returns a callable which receives
     the raw DBAPI connection after each one is created.   The callable
     is assembled into a first_connect/connect pool listener by the 
     connection strategy if non-None.   Provides a simpler interface 
     for dialects.
-    
+
   - StaticPool now initializes, disposes and recreates without 
     opening a new connection - the connection is only opened when 
     first requested. dispose() also works on AssertionPool now.
     [ticket:1728]
-    
+
 - metadata
   - Added the ability to strip schema information when using
     "tometadata" by passing "schema=None" as an argument. If schema
@@ -1853,13 +1853,13 @@ CHANGES
   - declarative now accepts mixin classes directly, as a means
     to provide common functional and column-based elements on
     all subclasses, as well as a means to propagate a fixed
-    set of __table_args__ or __mapper_args__ to subclasses.  
+    set of __table_args__ or __mapper_args__ to subclasses.
     For custom combinations of __table_args__/__mapper_args__ from
     an inherited mixin to local, descriptors can now be used.
     New details are all up in the Declarative documentation.
     Thanks to Chris Withers for putting up with my strife 
     on this. [ticket:1707]
-    
+
   - the __mapper_args__ dict is copied when propagating to a subclass,
     and is taken straight off the class __dict__ to avoid any
     propagation from the parent.  mapper inheritance already
@@ -1869,7 +1869,7 @@ CHANGES
   - An exception is raised when a single-table subclass specifies
     a column that is already present on the base class.
     [ticket:1732]
-    
+
 - mysql
   - Fixed reflection bug whereby when COLLATE was present, 
     nullable flag and server defaults would not be reflected.
@@ -1879,26 +1879,26 @@ CHANGES
     integer flags like UNSIGNED.
 
   - Further fixes for the mysql-connector dialect.  [ticket:1668]
-  
+
   - Composite PK table on InnoDB where the "autoincrement" column
     isn't first will emit an explicit "KEY" phrase within 
     CREATE TABLE thereby avoiding errors, [ticket:1496]
 
   - Added reflection/create table support for a wide range
     of MySQL keywords.  [ticket:1634]
-  
+
   - Fixed import error which could occur reflecting tables on
     a Windows host [ticket:1580]
-    
+
 - mssql
   - Re-established support for the pymssql dialect.
 
   - Various fixes for implicit returning, reflection,
     etc. - the MS-SQL dialects aren't quite complete
     in 0.6 yet (but are close)
-  
+
   - Added basic support for mxODBC [ticket:1710].
-  
+
   - Removed the text_as_varchar option.
 
 - oracle
@@ -1920,17 +1920,17 @@ CHANGES
      is emitted asking that the user seriously consider
      the usage of this difficult mode of operation.
      [ticket:1670]
-  
+
    - The except_() method now renders as MINUS on Oracle,
      which is more or less equivalent on that platform.
      [ticket:1712]
-   
+
    - Added support for rendering and reflecting 
      TIMESTAMP WITH TIME ZONE, i.e. TIMESTAMP(timezone=True).
      [ticket:651]
-     
+
    - Oracle INTERVAL type can now be reflected.
-     
+
 - sqlite
    - Added "native_datetime=True" flag to create_engine().
      This will cause the DATE and TIMESTAMP types to skip 
@@ -1947,7 +1947,7 @@ CHANGES
      creates/drops and basic round trip functionality.
      Does not yet include reflection or comprehensive
      support of unicode/special expressions/etc.
-     
+
 - examples
    - Changed the beaker cache example a bit to have a separate
      RelationCache option for lazyload caching.  This object
@@ -1971,11 +1971,11 @@ CHANGES
 
   - Platforms targeted now include Python 2.4/2.5/2.6, Python
     3.1, Jython2.5.
-    
+
 - orm
   - Changes to query.update() and query.delete():
       - the 'expire' option on query.update() has been renamed to
-        'fetch', thus matching that of query.delete().  
+        'fetch', thus matching that of query.delete().
         'expire' is deprecated and issues a warning.
 
       - query.update() and query.delete() both default to
@@ -2022,7 +2022,7 @@ CHANGES
   - Enhancements / Changes on Session.merge():
      - the "dont_load=True" flag on Session.merge() is deprecated
        and is now "load=False".
-    
+
      - Session.merge() is performance optimized, using half the
        call counts for "load=False" mode compared to 0.5 and
        significantly fewer SQL queries in the case of collections
@@ -2030,39 +2030,39 @@ CHANGES
 
      - merge() will not issue a needless merge of attributes if the
        given instance is the same instance which is already present.
-       
+
      - merge() now also merges the "options" associated with a given
        state, i.e. those passed through query.options() which follow
        along with an instance, such as options to eagerly- or
        lazyily- load various attributes.   This is essential for
        the construction of highly integrated caching schemes.  This
        is a subtle behavioral change vs. 0.5.
-       
+
      - A bug was fixed regarding the serialization of the "loader
        path" present on an instance's state, which is also necessary
        when combining the usage of merge() with serialized state
-       and associated options that should be preserved.  
-       
+       and associated options that should be preserved.
+
      - The all new merge() is showcased in a new comprehensive 
        example of how to integrate Beaker with SQLAlchemy.  See
        the notes in the "examples" note below.
-  
+
   - Primary key values can now be changed on a joined-table inheritance
     object, and ON UPDATE CASCADE will be taken into account when
     the flush happens.  Set the new "passive_updates" flag to False
     on mapper() when using SQLite or MySQL/MyISAM. [ticket:1362]
-    
+
   - flush() now detects when a primary key column was updated by
     an ON UPDATE CASCADE operation from another primary key, and
     can then locate the row for a subsequent UPDATE on the new PK
     value.  This occurs when a relation() is there to establish
     the relationship as well as passive_updates=True.  [ticket:1671]
-    
+
   - the "save-update" cascade will now cascade the pending *removed*
     values from a scalar or collection attribute into the new session 
     during an add() operation.  This so that the flush() operation
     will also delete or modify rows of those disconnected items.
-    
+
   - Using a "dynamic" loader with a "secondary" table now produces
     a query where the "secondary" table is *not* aliased.  This
     allows the secondary Table object to be used in the "order_by"
@@ -2075,25 +2075,25 @@ CHANGES
     the row.  This may be due to primaryjoin/secondaryjoin 
     conditions which aren't appropriate for an eager LEFT OUTER 
     JOIN or for other conditions.  [ticket:1643]
-    
+
   - an explicit check occurs when a synonym() is used with 
     map_column=True, when a ColumnProperty (deferred or otherwise)
     exists separately in the properties dictionary sent to mapper
     with the same keyname.   Instead of silently replacing 
     the existing property (and possible options on that property), 
     an error is raised.  [ticket:1633]
-    
+
   - a "dynamic" loader sets up its query criterion at construction
     time so that the actual query is returned from non-cloning
     accessors like "statement".
-    
+
   - the "named tuple" objects returned when iterating a
     Query() are now pickleable.
 
   - mapping to a select() construct now requires that you 
     make an alias() out of it distinctly.   This to eliminate
     confusion over such issues as [ticket:1542]
-    
+
   - query.join() has been reworked to provide more consistent 
     behavior and more flexibility (includes [ticket:1537])
 
@@ -2109,7 +2109,7 @@ CHANGES
   - query.get() can be used with a mapping to an outer join
     where one or more of the primary key values are None.
     [ticket:1135]
-    
+
   - query.from_self(), query.union(), others which do a 
     "SELECT * from (SELECT...)" type of nesting will do
     a better job translating column expressions within the subquery
@@ -2118,12 +2118,12 @@ CHANGES
     may break queries with literal expressions that do not have labels
     applied (i.e. literal('foo'), etc.)
     [ticket:1568]
-  
+
   - relation primaryjoin and secondaryjoin now check that they
     are column-expressions, not just clause elements.  this prohibits
     things like FROM expressions being placed there directly.
     [ticket:1622]
-    
+
   - `expression.null()` is fully understood the same way
     None is when comparing an object/collection-referencing
     attribute within query.filter(), filter_by(), etc.
@@ -2149,7 +2149,7 @@ CHANGES
      subclasses of RelationProperty) into the reverse reference. 
      The internal BackRef() is gone and backref() returns a plain 
      tuple that is understood by RelationProperty.
-     
+
    - The version_id_col feature on mapper() will raise a warning when
      used with dialects that don't support "rowcount" adequately.
      [ticket:1569]
@@ -2159,10 +2159,10 @@ CHANGES
      Select-statements have these options, and the only option
      used is "stream_results", and the only dialect which knows
      "stream_results" is psycopg2. 
-     
+
    - Query.yield_per() will set the "stream_results" statement
      option automatically.
-     
+
    - Deprecated or removed:
       * 'allow_null_pks' flag on mapper() is deprecated.  It does
         nothing now and the setting is "on" in all cases.
@@ -2210,9 +2210,9 @@ CHANGES
         expect a regular mapped object instance.
       * the 'engine' parameter to declarative_base() is removed.
         Use the 'bind' keyword argument.
-        
+
 - sql
-  
+
     - the "autocommit" flag on select() and text() as well
       as select().autocommit() are deprecated - now call
       .execution_options(autocommit=True) on either of those
@@ -2221,7 +2221,7 @@ CHANGES
     - the autoincrement flag on column now indicates the column
       which should be linked to cursor.lastrowid, if that method
       is used.  See the API docs for details.
-    
+
     - an executemany() now requires that all bound parameter
       sets require that all keys are present which are 
       present in the first bound parameter set.  The structure
@@ -2232,7 +2232,7 @@ CHANGES
       is not impacted.  For this reason defaults would otherwise 
       silently "fail" for missing parameters, so this is now guarded 
       against. [ticket:1566]
-      
+
     - returning() support is native to insert(), update(),
       delete(). Implementations of varying levels of
       functionality exist for Postgresql, Firebird, MSSQL and
@@ -2245,7 +2245,7 @@ CHANGES
       version in use supports it (a version number check is
       performed). This occurs if no end-user returning() was
       specified.
-    
+
     - union(), intersect(), except() and other "compound" types
       of statements have more consistent behavior w.r.t. 
       parenthesizing.   Each compound element embedded within 
@@ -2260,18 +2260,18 @@ CHANGES
       when nesting compound elements, the first one usually needs
       ".alias().select()" called on it to wrap it inside
       of a subquery.  [ticket:1665]
-      
+
     - insert() and update() constructs can now embed bindparam()
       objects using names that match the keys of columns.  These
       bind parameters will circumvent the usual route to those 
       keys showing up in the VALUES or SET clause of the generated
       SQL. [ticket:1579]
-      
+
     - the Binary type now returns data as a Python string
       (or a "bytes" type in Python 3), instead of the built-
       in "buffer" type.  This allows symmetric round trips
       of binary data. [ticket:1524]
-    
+
     - Added a tuple_() construct, allows sets of expressions
       to be compared to another set, typically with IN against
       composite primary keys or similar.  Also accepts an 
@@ -2279,7 +2279,7 @@ CHANGES
       have only one column" error message is removed - will
       rely upon the database to report problems with 
       col mismatch.
-        
+
     - User-defined "default" and "onupdate" callables which 
       accept a context should now call upon 
       "context.current_parameters" to get at the dictionary
@@ -2292,7 +2292,7 @@ CHANGES
       with underscores for dots, i.e. "dbo_master_table_column".
       This is a "friendly" label that behaves better
       in result sets. [ticket:1428]
-    
+
     - removed needless "counter" behavior with select()
       labelnames that match a column name in the table,
       i.e. generates "tablename_id" for "id", instead of
@@ -2301,7 +2301,7 @@ CHANGES
       named "tablename_id" - this is because
       the labeling logic is always applied to all columns
       so a naming conflict will never occur.
-    
+
     - calling expr.in_([]), i.e. with an empty list, emits a warning
       before issuing the usual "expr != expr" clause.  The
       "expr != expr" can be very expensive, and it's preferred
@@ -2312,7 +2312,7 @@ CHANGES
 
     - Added "execution_options()" to select()/text(), which set the
       default options for the Connection.  See the note in "engines".
-       
+
     - Deprecated or removed:
         * "scalar" flag on select() is removed, use 
           select.as_scalar().
@@ -2322,12 +2322,12 @@ CHANGES
           the new returning() method.
         * fold_equivalents flag on join is deprecated (will remain
           until [ticket:1131] is implemented)
-    
+
 - engines
   - transaction isolation level may be specified with
     create_engine(... isolation_level="..."); available on
     postgresql and sqlite. [ticket:443]
-    
+
   - Connection has execution_options(), generative method
     which accepts keywords that affect how the statement 
     is executed w.r.t. the DBAPI.   Currently supports 
@@ -2337,11 +2337,11 @@ CHANGES
     option from select() and text().   select() and
     text() also have .execution_options() as well as 
     ORM Query().
-    
+
   - fixed the import for entrypoint-driven dialects to 
     not rely upon silly tb_info trick to determine import
     error status.  [ticket:1630]
-    
+
   - added first() method to ResultProxy, returns first row and
     closes result set immediately.
 
@@ -2351,7 +2351,7 @@ CHANGES
   - RowProxy no longer has a close() method, as the row no longer
     maintains a reference to the parent.  Call close() on 
     the parent ResultProxy instead, or use autoclose.
-    
+
   - ResultProxy internals have been overhauled to greatly reduce
     method call counts when fetching columns.  Can provide a large 
     speed improvement (up to more than 100%) when fetching large 
@@ -2369,31 +2369,31 @@ CHANGES
 
   - the last_inserted_ids() method has been renamed to the
     descriptor "inserted_primary_key".
-    
+
   - setting echo=False on create_engine() now sets the loglevel
     to WARN instead of NOTSET.  This so that logging can be
     disabled for a particular engine even if logging
     for "sqlalchemy.engine" is enabled overall.  Note that the
     default setting of "echo" is `None`. [ticket:1554]
-  
+
   - ConnectionProxy now has wrapper methods for all transaction
     lifecycle events, including begin(), rollback(), commit()
     begin_nested(), begin_prepared(), prepare(), release_savepoint(),
     etc.
-    
+
   - Connection pool logging now uses both INFO and DEBUG
     log levels for logging.  INFO is for major events such
     as invalidated connections, DEBUG for all the acquire/return
     logging.  `echo_pool` can be False, None, True or "debug"
     the same way as `echo` works.
-  
+
   - All pyodbc-dialects now support extra pyodbc-specific 
     kw arguments 'ansi', 'unicode_results', 'autocommit'.
     [ticket:1621]
 
   - the "threadlocal" engine has been rewritten and simplified 
     and now supports SAVEPOINT operations.
-    
+
   - deprecated or removed
       * result.last_inserted_ids() is deprecated.  Use 
         result.inserted_primary_key
@@ -2404,22 +2404,22 @@ CHANGES
         now has those methods.   All four methods accept
         *args and **kwargs which are passed to the given callable, 
         as well as the operating connection.
-        
+
 - schema
     - the `__contains__()` method of `MetaData` now accepts
       strings or `Table` objects as arguments.  If given
       a `Table`, the argument is converted to `table.key` first,
       i.e. "[schemaname.]<tablename>" [ticket:1541]
-      
+
     - deprecated MetaData.connect() and
       ThreadLocalMetaData.connect() have been removed - send
       the "bind" attribute to bind a metadata.
 
     - deprecated metadata.table_iterator() method removed (use
       sorted_tables)
-    
+
     - deprecated PassiveDefault - use DefaultClause.
-    
+
     - the "metadata" argument is removed from DefaultGenerator
       and subclasses, but remains locally present on Sequence,
       which is a standalone construct in DDL.
@@ -2433,12 +2433,12 @@ CHANGES
         - PrimaryKeyConstraint.remove()
       These should be constructed declaratively (i.e. in one
       construction).
-    
+
     - The "start" and "increment" attributes on Sequence now
       generate "START WITH" and "INCREMENT BY" by default,
       on Oracle and Postgresql.  Firebird doesn't support
       these keywords right now.  [ticket:1545]
-      
+
     - UniqueConstraint, Index, PrimaryKeyConstraint all accept
       lists of column names or column objects as arguments.
 
@@ -2450,40 +2450,40 @@ CHANGES
         - Column.metadata   (get via column.table.metadata)
         - Column.sequence   (use column.default)
         - ForeignKey(constraint=some_parent) (is now private _constraint)
-        
+
     - The use_alter flag on ForeignKey is now a shortcut option
       for operations that can be hand-constructed using the
       DDL() event system. A side effect of this refactor is
       that ForeignKeyConstraint objects with use_alter=True
       will *not* be emitted on SQLite, which does not support
       ALTER for foreign keys.
-    
+
     - ForeignKey and ForeignKeyConstraint objects now correctly
       copy() all their public keyword arguments.  [ticket:1605]
-      
+
 - Reflection/Inspection
     - Table reflection has been expanded and generalized into 
       a new API called "sqlalchemy.engine.reflection.Inspector".
       The Inspector object provides fine-grained information about
       a wide variety of schema information, with room for expansion,
       including table names, column names, view definitions, sequences,
-      indexes, etc.  
-    
+      indexes, etc.
+
     - Views are now reflectable as ordinary Table objects.  The same
       Table constructor is used, with the caveat that "effective" 
       primary and foreign key constraints aren't part of the reflection
       results; these have to be specified explicitly if desired.
-    
+
     - The existing autoload=True system now uses Inspector underneath
       so that each dialect need only return "raw" data about tables
       and other objects - Inspector is the single place that information
       is compiled into Table objects so that consistency is at a maximum.
-      
+
 - DDL
     - the DDL system has been greatly expanded.  the DDL() class
       now extends the more generic DDLElement(), which forms the basis
       of many new constructs:
-      
+
         - CreateTable()
         - DropTable()
         - AddConstraint()
@@ -2492,14 +2492,14 @@ CHANGES
         - DropIndex()
         - CreateSequence()
         - DropSequence()
-        
+
        These support "on" and "execute-at()" just like plain DDL() 
        does.  User-defined DDLElement subclasses can be created and 
        linked to a compiler using the sqlalchemy.ext.compiler extension.
 
     - The signature of the "on" callable passed to DDL() and
       DDLElement() is revised as follows:
-      
+
         "ddl" - the DDLElement object itself.
         "event" - the string event name.
         "target" - previously "schema_item", the Table or 
@@ -2523,7 +2523,7 @@ CHANGES
 
     - the setuptools entrypoint for external dialects is now 
       called "sqlalchemy.dialects".
-      
+
     - the "owner" keyword argument is removed from Table. Use
       "schema" to represent any namespaces to be prepended to
       the table name.
@@ -2538,17 +2538,17 @@ CHANGES
 
     - cached TypeEngine classes are cached per-dialect class 
       instead of per-dialect.
-    
+
     - new UserDefinedType should be used as a base class for
       new types, which preserves the 0.5 behavior of 
       get_col_spec().
-      
+
     - The result_processor() method of all type classes now 
       accepts a second argument "coltype", which is the DBAPI
       type argument from cursor.description.  This argument
       can help some types decide on the most efficient processing
       of result values.
-      
+
     - Deprecated Dialect.get_params() removed.
 
     - Dialect.get_rowcount() has been renamed to a descriptor
@@ -2561,7 +2561,7 @@ CHANGES
       ExecutionContext.  Dialects which support sequences should
       add a `fire_sequence()` method to their execution context
       implementation.  [ticket:1566]
-      
+
     - Functions and operators generated by the compiler now use
       (almost) regular dispatch functions of the form
       "visit_<opname>" and "visit_<funcname>_fn" to provide
@@ -2575,7 +2575,7 @@ CHANGES
 - postgresql
     - New dialects: pg8000, zxjdbc, and pypostgresql
       on py3k.
-      
+
     - The "postgres" dialect is now named "postgresql" !
       Connection strings look like:
 
@@ -2601,24 +2601,24 @@ CHANGES
              the older "postgres_returning" and
              "postgres_where" names still work with a
              deprecation warning.
-    
+
     - "postgresql_where" now accepts SQL expressions which 
       can also include literals, which will be quoted as needed.
-      
+
     - The psycopg2 dialect now uses psycopg2's "unicode extension"
       on all new connections, which allows all String/Text/etc.
       types to skip the need to post-process bytestrings into
       unicode (an expensive step due to its volume).  Other 
       dialects which return unicode natively (pg8000, zxjdbc)
       also skip unicode post-processing.
-      
+
     - Added new ENUM type, which exists as a schema-level
       construct and extends the generic Enum type.  Automatically
       associates itself with tables and their parent metadata
       to issue the appropriate CREATE TYPE/DROP TYPE 
       commands as needed, supports unicode labels, supports
       reflection.  [ticket:1511]
-    
+
     - INTERVAL supports an optional "precision" argument 
       corresponding to the argument that PG accepts.
 
@@ -2630,17 +2630,17 @@ CHANGES
       %(foobar)s however and SQLA doesn't want to add overhead
       just to treat that one non-existent use case.
       [ticket:1279]
-    
+
     - Inserting NULL into a primary key + foreign key column
       will allow the "not null constraint" error to raise,
       not an attempt to execute a nonexistent "col_id_seq" 
       sequence.  [ticket:1516]
-    
+
     - autoincrement SELECT statements, i.e. those which 
       select from a procedure that modifies rows, now work 
       with server-side cursor mode (the named cursor isn't 
       used for such statements.)
-    
+
     - postgresql dialect can properly detect pg "devel" version
       strings, i.e. "8.5devel" [ticket:1636]
 
@@ -2650,17 +2650,17 @@ CHANGES
       used for the statement. If false, they will not be used, even
       if "server_side_cursors" is true on the
       connection. [ticket:1619]
-      
+
 - mysql
     - New dialects: oursql, a new native dialect, 
       MySQL Connector/Python, a native Python port of MySQLdb,
       and of course zxjdbc on Jython.
-    
+
     - VARCHAR/NVARCHAR will not render without a length, raises
       an error before passing to MySQL.   Doesn't impact 
       CAST since VARCHAR is not allowed in MySQL CAST anyway,
       the dialect renders CHAR/NCHAR in those cases.
-      
+
     - all the _detect_XXX() functions now run once underneath
       dialect.initialize()
 
@@ -2668,26 +2668,26 @@ CHANGES
       MySQLdb can't handle % signs in SQL when executemany() is used,
       and SQLA doesn't want to add overhead just to treat that one 
       non-existent use case. [ticket:1279]
-    
+
     - the BINARY and MSBinary types now generate "BINARY" in all
       cases.  Omitting the "length" parameter will generate
       "BINARY" with no length.  Use BLOB to generate an unlengthed
       binary column.
-      
+
     - the "quoting='quoted'" argument to MSEnum/ENUM is deprecated.
       It's best to rely upon the automatic quoting.
-      
+
     - ENUM now subclasses the new generic Enum type, and also handles
       unicode values implicitly, if the given labelnames are unicode
       objects.
-    
+
     - a column of type TIMESTAMP now defaults to NULL if
       "nullable=False" is not passed to Column(), and no default
       is present. This is now consistent with all other types, 
       and in the case of TIMESTAMP explictly renders "NULL" 
       due to MySQL's "switching" of default nullability
       for TIMESTAMP columns. [ticket:1539]
-      
+
 - oracle
     - unit tests pass 100% with cx_oracle !
 
@@ -2696,24 +2696,24 @@ CHANGES
       later of cx_oracle.
 
     - an NCLOB type is added to the base types.
-    
+
     - use_ansi=False won't leak into the FROM/WHERE clause of
       a statement that's selecting from a subquery that also
       uses JOIN/OUTERJOIN.
-      
+
     - added native INTERVAL type to the dialect.  This supports
       only the DAY TO SECOND interval type so far due to lack 
       of support in cx_oracle for YEAR TO MONTH. [ticket:1467]
-      
+
     - usage of the CHAR type results in cx_oracle's 
       FIXED_CHAR dbapi type being bound to statements.
-      
+
     - the Oracle dialect now features NUMBER which intends
       to act justlike Oracle's NUMBER type.  It is the primary
       numeric type returned by table reflection and attempts
       to return Decimal()/float/int based on the precision/scale
       parameters.  [ticket:885]
-      
+
     - func.char_length is a generic function for LENGTH
 
     - ForeignKey() which includes onupdate=<value> will emit a
@@ -2729,15 +2729,15 @@ CHANGES
 
     - using new dialect.initialize() feature to set up
       version-dependent behavior.
-    
+
     - using types.BigInteger with Oracle will generate
       NUMBER(19) [ticket:1125]
-    
+
     - "case sensitivity" feature will detect an all-lowercase
       case-sensitive column name during reflect and add 
       "quote=True" to the generated Column, so that proper
       quoting is maintained.
-      
+
 - firebird
     - the keys() method of RowProxy() now returns the result
       column names *normalized* to be SQLAlchemy case
@@ -2797,7 +2797,7 @@ CHANGES
       applies the SQLite keyword "AUTOINCREMENT" to the single integer
       primary key column when generating DDL. Will prevent generation of 
       a separate PRIMARY KEY constraint. [ticket:1016]
-      
+
 - new dialects
     - postgresql+pg8000
     - postgresql+pypostgresql (partial)
@@ -2821,13 +2821,13 @@ CHANGES
       parameters. In particular, Numeric, Float, NUMERIC,
       FLOAT, DECIMAL don't generate any length or scale unless
       specified.
-    
+
     - types.Binary is renamed to types.LargeBinary, it only
-      produces BLOB, BYTEA, or a similar "long binary" type.   
+      produces BLOB, BYTEA, or a similar "long binary" type.
       New base BINARY and VARBINARY
       types have been added to access these MySQL/MS-SQL specific
       types in an agnostic way [ticket:1664].
-      
+
     - String/Text/Unicode types now skip the unicode() check
       on each result column value if the dialect has 
       detected the DBAPI as returning Python unicode objects
@@ -2846,13 +2846,13 @@ CHANGES
       Time, Date and DateTime on Sqlite, ARRAY on Postgresql,
       Time on MySQL, Numeric(as_decimal=False) on MySQL, oursql and 
       pypostgresql, DateTime on cx_oracle and LOB-based types on cx_oracle.
-      
+
     - Reflection of types now returns the exact UPPERCASE
       type within types.py, or the UPPERCASE type within
       the dialect itself if the type is not a standard SQL 
       type.  This means reflection now returns more accurate
-      information about reflected types.  
-    
+      information about reflected types.
+
     - Added a new Enum generic type. Enum is a schema-aware object
       to support databases which require specific DDL in order to
       use enum or equivalent; in the case of PG it handles the
@@ -2860,13 +2860,13 @@ CHANGES
       native enum support will by generate VARCHAR + an inline CHECK
       constraint to enforce the enum.
       [ticket:1109] [ticket:1511]
-    
+
     - The Interval type includes a "native" flag which controls
       if native INTERVAL types (postgresql + oracle) are selected
       if available, or not.  "day_precision" and "second_precision"
       arguments are also added which propagate as appropriately
       to these native types. Related to [ticket:1467].
-      
+
     - The Boolean type, when used on a backend that doesn't 
       have native boolean support, will generate a CHECK 
       constraint "col IN (0, 1)" along with the int/smallint-
@@ -2875,14 +2875,14 @@ CHANGES
       Note that MySQL has no native boolean *or* CHECK constraint
       support so this feature isn't available on that platform.
       [ticket:1589]
-      
+
     - PickleType now uses == for comparison of values when
       mutable=True, unless the "comparator" argument with a
       comparsion function is specified to the type. Objects
       being pickled will be compared based on identity (which
       defeats the purpose of mutable=True) if __eq__() is not
       overridden or a comparison function is not provided.
-      
+
     - The default "precision" and "scale" arguments of Numeric
       and Float have been removed and now default to None.
       NUMERIC and FLOAT will be rendered with no numeric
@@ -2890,7 +2890,7 @@ CHANGES
 
     - AbstractType.get_search_list() is removed - the games
       that was used for are no longer necessary.
-    
+
     - Added a generic BigInteger type, compiles to 
       BIGINT or NUMBER(19). [ticket:1125]
 
@@ -2904,15 +2904,15 @@ CHANGES
 
     - sqlsoup db.<sometable>.update() and delete() now call
       query(cls).update() and delete(), respectively.
-    
+
     - sqlsoup now has execute() and connection(), which call upon
       the Session methods of those names, ensuring that the bind is
       in terms of the SqlSoup object's bind.
-    
+
     - sqlsoup objects no longer have the 'query' attribute - it's
       not needed for sqlsoup's usage paradigm and it gets in the
       way of a column that is actually named 'query'.
-      
+
     - The signature of the proxy_factory callable passed to 
       association_proxy is now (lazy_collection, creator, 
       value_attr, association_proxy), adding a fourth argument
@@ -2923,7 +2923,7 @@ CHANGES
     - association_proxy now has basic comparator methods .any(),
       .has(), .contains(), ==, !=, thanks to Scott Torborg.
       [ticket:1372]
-      
+
 - examples
     - The "query_cache" examples have been removed, and are replaced
       with a fully comprehensive approach that combines the usage of
@@ -2931,13 +2931,13 @@ CHANGES
       the caching characteristics of a particular Query, which 
       can also be invoked deep within an object graph when lazily
       loading related objects.  See /examples/beaker_caching/README.
-    
+
 0.5.9
 =====
 - sql
     - Fixed erroneous self_group() call in expression package.
       [ticket:1661]
-    
+
 0.5.8
 =====
 - sql
@@ -2945,15 +2945,15 @@ CHANGES
       unnamed Column objects. This allows easy creation of 
       declarative helpers which place common columns on multiple 
       subclasses.
-    
+
     - Default generators like Sequence() translate correctly
       across a copy() operation.
-      
+
     - Sequence() and other DefaultGenerator objects are accepted 
       as the value for the "default" and "onupdate" keyword
       arguments of Column, in addition to being accepted
-      positionally.  
-      
+      positionally.
+
     - Fixed a column arithmetic bug that affected column
       correspondence for cloned selectables which contain
       free-standing column expressions.   This bug is
@@ -2961,7 +2961,7 @@ CHANGES
       ORM behavior only availble in 0.6 via [ticket:1568], 
       but is more correct at the SQL expression level 
       as well. [ticket:1617]
-    
+
 - postgresql
     - The extract() function, which was slightly improved in
       0.5.7, needed a lot more work to generate the correct
@@ -2981,28 +2981,28 @@ CHANGES
     - contains_eager() now works with the automatically 
       generated subquery that results when you say 
       "query(Parent).join(Parent.somejoinedsubclass)", i.e. 
-      when Parent joins to a joined-table-inheritance subclass.  
+      when Parent joins to a joined-table-inheritance subclass.
       Previously contains_eager() would erroneously add the 
       subclass table to the query separately producing a 
       cartesian product.  An example is in the ticket
       description.  [ticket:1543]
-    
+
     - query.options() now only propagate to loaded objects
       for potential further sub-loads only for options where
       such behavior is relevant, keeping
       various unserializable options like those generated
       by contains_eager() out of individual instance states.
       [ticket:1553]
-    
+
     - Session.execute() now locates table- and 
       mapper-specific binds based on a passed
       in expression which is an insert()/update()/delete() 
       construct. [ticket:1054]
-      
+
     - Session.merge() now properly overwrites a many-to-one or 
       uselist=False attribute to None if the attribute 
       is also None in the given object to be merged.
-     
+
     - Fixed a needless select which would occur when merging
       transient objects that contained a null primary key
       identifier.  [ticket:1618]
@@ -3013,14 +3013,14 @@ CHANGES
       duplicate extensions, such as backref populators,
       from being inserted into the list.
       [ticket:1585]
-    
+
     - Fixed the call to get_committed_value() on CompositeProperty.
       [ticket:1504]
 
     - Fixed bug where Query would crash if a join() with no clear
       "left" side were called when a non-mapped column entity
       appeared in the columns list. [ticket:1602]
-    
+
     - Fixed bug whereby composite columns wouldn't load properly
       when configured on a joined-table subclass, introduced in
       version 0.5.6 as a result of the fix for [ticket:1480].
@@ -3034,26 +3034,26 @@ CHANGES
       combinations of reflected and non-reflected types to work
       with 0.5 style type reflection, such as PGText/Text (note 0.6 
       reflects types as their generic versions).   [ticket:1556]
-    
+
     - Fixed bug in query.update() when passing Cls.attribute
       as keys in the value dict and using synchronize_session='expire'
       ('fetch' in 0.6). [ticket:1436]
-      
+
 - sql
     - Fixed bug in two-phase transaction whereby commit() method
       didn't set the full state which allows subsequent close()
       call to succeed. [ticket:1603]
-      
+
     - Fixed the "numeric" paramstyle, which apparently is the
       default paramstyle used by Informixdb.
-      
+
     - Repeat expressions in the columns clause of a select
       are deduped based on the identity of each clause element,
       not the actual string.  This allows positional 
       elements to render correctly even if they all render
       identically, such as "qmark" style bind parameters.
       [ticket:1574]
-    
+
     - The cursor associated with connection pool connections
       (i.e. _CursorFairy) now proxies `__iter__()` to the 
       underlying cursor correctly. [ticket:1632]
@@ -3066,14 +3066,14 @@ CHANGES
     - Fixed bug preventing alias() of an alias() from being
       cloned or adapted (occurs frequently in ORM operations).
       [ticket:1641]
-      
+
 - sqlite
     - sqlite dialect properly generates CREATE INDEX for a table
       that is in an alternate schema.  [ticket:1439]
-      
+
 - postgresql
     - Added support for reflecting the DOUBLE PRECISION type,
-      via a new postgres.PGDoublePrecision object.  
+      via a new postgres.PGDoublePrecision object.
       This is postgresql.DOUBLE_PRECISION in 0.6.
       [ticket:1085]
 
@@ -3087,7 +3087,7 @@ CHANGES
 
     - Fixed the behavior of extract() to apply operator
       precedence rules to the "::" operator when applying
-      the "timestamp" cast - ensures proper parenthesization.  
+      the "timestamp" cast - ensures proper parenthesization.
       [ticket:1611]
 
 - mssql
@@ -3101,7 +3101,7 @@ CHANGES
        table generated by Oracle when "index only tables"
        with overflow are used.  These tables aren't accessible
        via SQL and can't be reflected.  [ticket:1637]
-       
+
 - ext 
     - A column can be added to a joined-table declarative 
       superclass after the class has been constructed 
@@ -3114,10 +3114,10 @@ CHANGES
       Comparing equivalence of columns in the ORM is best 
       accomplished using col1.shares_lineage(col2).
       [ticket:1491]
-    
+
     - Removed unused `load()` method from ShardedQuery.
       [ticket:1606]
-      
+
 0.5.6
 =====
 - orm
@@ -3128,60 +3128,60 @@ CHANGES
     - Fixed bug which disallowed one side of a many-to-many 
       bidirectional reference to declare itself as "viewonly"
       [ticket:1507]
-    
+
     - Added an assertion that prevents a @validates function
       or other AttributeExtension from loading an unloaded
       collection such that internal state may be corrupted.
       [ticket:1526]
-      
+
     - Fixed bug which prevented two entities from mutually
       replacing each other's primary key values within a single
       flush() for some orderings of operations.  [ticket:1519]
-      
+
     - Fixed an obscure issue whereby a joined-table subclass
       with a self-referential eager load on the base class
       would populate the related object's "subclass" table with
       data from the "subclass" table of the parent.
       [ticket:1485]
-    
+
     - relations() now have greater ability to be "overridden",
       meaning a subclass that explicitly specifies a relation()
       overriding that of the parent class will be honored
       during a flush.  This is currently to support 
       many-to-many relations from concrete inheritance setups.
       Outside of that use case, YMMV.  [ticket:1477]
-    
+
     - Squeezed a few more unnecessary "lazy loads" out of 
       relation().  When a collection is mutated, many-to-one
       backrefs on the other side will not fire off to load
-      the "old" value, unless "single_parent=True" is set.  
+      the "old" value, unless "single_parent=True" is set.
       A direct assignment of a many-to-one still loads 
       the "old" value in order to update backref collections 
       on that value, which may be present in the session 
       already, thus maintaining the 0.5 behavioral contract.
       [ticket:1483]
-      
+
     - Fixed bug whereby a load/refresh of joined table
       inheritance attributes which were based on 
       column_property() or similar would fail to evaluate.
       [ticket:1480]
-    
+
     - Improved support for MapperProperty objects overriding
       that of an inherited mapper for non-concrete 
       inheritance setups - attribute extensions won't randomly
       collide with each other.  [ticket:1488]
-    
+
     - UPDATE and DELETE do not support ORDER BY, LIMIT, OFFSET,
       etc. in standard SQL.  Query.update() and Query.delete()
       now raise an exception if any of limit(), offset(),
       order_by(), group_by(), or distinct() have been
       called. [ticket:1487]
-      
+
     - Added AttributeExtension to sqlalchemy.orm.__all__
-      
+
     - Improved error message when query() is called with
       a non-SQL /entity expression. [ticket:1476]
-    
+
     - Using False or 0 as a polymorphic discriminator now
       works on the base class as well as a subclass.
       [ticket:1440]
@@ -3205,12 +3205,12 @@ CHANGES
       in query.join() which would fail to issue correctly
       if the query was against a pure SQL construct.
       [ticket:1522]
-    
+
     - Fixed a somewhat hypothetical issue which would result
       in the wrong primary key being calculated for a mapper
       using the old polymorphic_union function - but this
       is old stuff.  [ticket:1486]
-      
+
 - sql
     - Fixed column.copy() to copy defaults and onupdates.
       [ticket:1373]
@@ -3219,11 +3219,11 @@ CHANGES
       the string "field" argument was getting treated as a 
       ClauseElement, causing various errors within more 
       complex SQL transformations.
-      
+
     - Unary expressions such as DISTINCT propagate their 
       type handling to result sets, allowing conversions like
       unicode and such to take place.  [ticket:1420]
-    
+
     - Fixed bug in Table and Column whereby passing empty
       dict for "info" argument would raise an exception.
       [ticket:1482]
@@ -3231,7 +3231,7 @@ CHANGES
 - oracle
     - Backported 0.6 fix for Oracle alias names not getting
       truncated.  [ticket:1309]
-      
+
 - ext
    - The collection proxies produced by associationproxy are now
      pickleable.  A user-defined proxy_factory however
@@ -3246,7 +3246,7 @@ CHANGES
      in string expressions sent to primaryjoin/secondaryjoin/
      secondary - the name is pulled from the MetaData of the
      declarative base.  [ticket:1527]
-     
+
    - A column can be added to a joined-table subclass after
      the class has been constructed (i.e. via class-level
      attribute assignment).  The column is added to the underlying
@@ -3254,12 +3254,12 @@ CHANGES
      "join" to include the new column, instead of raising
      an error about "no such column, use column_property()
      instead".  [ticket:1523]
-     
+
 - test
    - Added examples into the test suite so they get exercised
      regularly and cleaned up a couple deprecation warnings.
 
-     
+
 0.5.5
 =======
 - general
@@ -3361,7 +3361,7 @@ CHANGES
 - sql
     - Repaired the printing of SQL exceptions which are not 
       based on parameters or are not executemany() style.
-      
+
 - postgresql
     - Deprecated the hardcoded TIMESTAMP function, which when
       used as func.TIMESTAMP(value) would render "TIMESTAMP value".
@@ -3370,15 +3370,15 @@ CHANGES
       uppercase is also inappropriate and there's lots of other
       PG casts that we'd need to support.  So instead, use
       text constructs i.e. select(["timestamp '12/05/09'"]).
-      
-      
+
+
 0.5.4p1
 =======
 
 - orm
     - Fixed an attribute error introduced in 0.5.4 which would 
       occur when merge() was used with an incomplete object.
-    
+
 0.5.4
 =====
 
@@ -3386,55 +3386,55 @@ CHANGES
     - Significant performance enhancements regarding Sessions/flush()
       in conjunction with large mapper graphs, large numbers of 
       objects:
-      
+
       - Removed all* O(N) scanning behavior from the flush() process,
         i.e. operations that were scanning the full session, 
         including an extremely expensive one that was erroneously
         assuming primary key values were changing when this 
         was not the case.
-        
+
         * one edge case remains which may invoke a full scan,
           if an existing primary key attribute is modified
           to a new value.
-      
+
       - The Session's "weak referencing" behavior is now *full* -
         no strong references whatsoever are made to a mapped object
         or related items/collections in its __dict__.  Backrefs and 
         other cycles in objects no longer affect the Session's ability 
         to lose all references to unmodified objects.  Objects with 
-        pending changes still are maintained strongly until flush.  
+        pending changes still are maintained strongly until flush.
         [ticket:1398]
-        
+
         The implementation also improves performance by moving
         the "resurrection" process of garbage collected items
         to only be relevant for mappings that map "mutable" 
         attributes (i.e. PickleType, composite attrs).  This removes
         overhead from the gc process and simplifies internal 
         behavior.
-        
+
         If a "mutable" attribute change is the sole change on an object 
         which is then dereferenced, the mapper will not have access to 
         other attribute state when the UPDATE is issued.  This may present 
         itself differently to some MapperExtensions.
-        
+
         The change also affects the internal attribute API, but not
         the AttributeExtension interface nor any of the publically
         documented attribute functions.
-        
+
       - The unit of work no longer genererates a graph of "dependency"
         processors for the full graph of mappers during flush(), instead
         creating such processors only for those mappers which represent
         objects with pending changes.  This saves a tremendous number
         of method calls in the context of a large interconnected 
         graph of mappers.
-        
+
       - Cached a wasteful "table sort" operation that previously
         occured multiple times per flush, also removing significant
         method call count from flush().
-        
+
       - Other redundant behaviors have been simplified in 
         mapper._save_obj().
-      
+
     - Modified query_cls on DynamicAttributeImpl to accept a full
       mixin version of the AppenderQuery, which allows subclassing
       the AppenderMixin.
@@ -3442,7 +3442,7 @@ CHANGES
     - The "polymorphic discriminator" column may be part of a 
       primary key, and it will be populated with the correct 
       discriminator value.  [ticket:1300]
-      
+
     - Fixed the evaluator not being able to evaluate IS NULL clauses.
 
     - Fixed the "set collection" function on "dynamic" relations to
@@ -3450,12 +3450,12 @@ CHANGES
       be assigned to a pending parent instance, otherwise modified
       events would not be fired correctly.  Set collection is now
       compatible with merge(), fixes [ticket:1352].
-    
+
     - Allowed pickling of PropertyOption objects constructed with
       instrumented descriptors; previously, pickle errors would occur 
       when pickling an object which was loaded with a descriptor-based 
       option, such as query.options(eagerload(MyClass.foo)).
-      
+
     - Lazy loader will not use get() if the "lazy load" SQL clause
       matches the clause used by get(), but contains some parameters
       hardcoded.  Previously the lazy strategy would fail with the
@@ -3471,15 +3471,15 @@ CHANGES
       the need in most cases for per-instance/attribute loader 
       objects, improving load speed and memory overhead for
       individual instances. [ticket:1391]
-      
+
     - Fixed another location where autoflush was interfering
       with session.merge().  autoflush is disabled completely
       for the duration of merge() now. [ticket:1360]
-    
+
     - Fixed bug which prevented "mutable primary key" dependency
       logic from functioning properly on a one-to-one
       relation().  [ticket:1406]
-      
+
     - Fixed bug in relation(), introduced in 0.5.3, 
       whereby a self referential relation
       from a base class to a joined-table subclass would 
@@ -3488,11 +3488,11 @@ CHANGES
     - Fixed obscure mapper compilation issue when inheriting
       mappers are used which would result in un-initialized
       attributes.
-      
+
     - Fixed documentation for session weak_identity_map - 
       the default value is True, indicating a weak
       referencing map in use.
-      
+
     - Fixed a unit of work issue whereby the foreign
       key attribute on an item contained within a collection 
       owned by an object being deleted would not be set to
@@ -3505,7 +3505,7 @@ CHANGES
       condition in the foreign_keys or remote_side collection.  Whereas
       previously it was just nonsensical, but would succeed in a 
       non-deterministic way.
-      
+
 - schema
     - Added a quote_schema() method to the IdentifierPreparer class
       so that dialects can override how schemas get handled. This
@@ -3519,12 +3519,12 @@ CHANGES
       handy as an alternative to text() when you'd like to 
       build a construct that has database-specific compilations.
       See the extension docs for details.
-      
+
     - Exception messages are truncated when the list of bound 
       parameters is larger than 10, preventing enormous
       multi-page exceptions from filling up screens and logfiles
       for large executemany() statements. [ticket:1413]
-      
+
     - ``sqlalchemy.extract()`` is now dialect sensitive and can
       extract components of timestamps idiomatically across the
       supported databases, including SQLite.
@@ -3537,7 +3537,7 @@ CHANGES
     - Reflecting a FOREIGN KEY construct will take into account
       a dotted schema.tablename combination, if the foreign key
       references a table in a remote schema. [ticket:1405]
-      
+
 - mssql
     - Modified how savepoint logic works to prevent it from
       stepping on non-savepoint oriented routines. Savepoint
@@ -3571,7 +3571,7 @@ CHANGES
       one side of the link and not the other, so supporting
       this operation leads to misleading results.
       [ticket:1315]
-    
+
     - Query now implements __clause_element__() which produces
       its selectable, which means a Query instance can be accepted 
       in many SQL expressions, including col.in_(query), 
@@ -3580,14 +3580,14 @@ CHANGES
 
     - Query.join() can now construct multiple FROM clauses, if 
       needed.  Such as, query(A, B).join(A.x).join(B.y)
-      might say SELECT A.*, B.* FROM A JOIN X, B JOIN Y.  
+      might say SELECT A.*, B.* FROM A JOIN X, B JOIN Y.
       Eager loading can also tack its joins onto those 
       multiple FROM clauses.  [ticket:1337]
 
     - Fixed bug in dynamic_loader() where append/remove events
       after construction time were not being propagated to the 
       UOW to pick up on flush(). [ticket:1347]
-      
+
     - Fixed bug where column_prefix wasn't being checked before
       not mapping an attribute that already had class-level 
       name present.
@@ -3598,48 +3598,48 @@ CHANGES
       in the database.  Presents some degree of a workaround for 
       [ticket:1315], although we are considering removing the 
       flush([objects]) feature altogether.
-    
+
     - Session.scalar() now converts raw SQL strings to text()
       the same way Session.execute() does and accepts same 
       alternative **kw args.
-      
+
     - improvements to the "determine direction" logic of 
       relation() such that the direction of tricky situations 
       like mapper(A.join(B)) -> relation-> mapper(B) can be
       determined.
-      
+
     - When flushing partial sets of objects using session.flush([somelist]),
       pending objects which remain pending after the operation won't
       inadvertently be added as persistent. [ticket:1306]
-     
+
     - Added "post_configure_attribute" method to InstrumentationManager,
       so that the "listen_for_events.py" example works again.
       [ticket:1314]
-    
+
     - a forward and complementing backwards reference which are both
       of the same direction, i.e. ONETOMANY or MANYTOONE, 
-      is now detected, and an error message is raised.   
+      is now detected, and an error message is raised.
       Saves crazy CircularDependencyErrors later on.
-        
+
     - Fixed bugs in Query regarding simultaneous selection of 
       multiple joined-table inheritance entities with common base 
       classes:
-      
+
       - previously the adaption applied to "B" on 
         "A JOIN B" would be erroneously partially applied 
         to "A".
-      
+
       - comparisons on relations (i.e. A.related==someb)
         were not getting adapted when they should.
-      
+
       - Other filterings, like 
         query(A).join(A.bs).filter(B.foo=='bar'), were erroneously
         adapting "B.foo" as though it were an "A".
-    
+
      - Fixed adaptation of EXISTS clauses via any(), has(), etc.
        in conjunction with an aliased object on the left and 
        of_type() on the right.  [ticket:1325]
-       
+
      - Added an attribute helper method ``set_committed_value`` in 
        sqlalchemy.orm.attributes.  Given an object, attribute name,
        and value, will set the value on the object as part of its
@@ -3650,17 +3650,17 @@ CHANGES
      - Query won't fail with weakref error when a non-mapper/class
        instrumented descriptor is passed, raises 
        "Invalid column expession".
-    
+
      - Query.group_by() properly takes into account aliasing applied
        to the FROM clause, such as with select_from(), using
        with_polymorphic(), or using from_self().
-        
+
 - sql
     - An alias() of a select() will convert to a "scalar subquery"
       when used in an unambiguously scalar context, i.e. it's used 
       in a comparison operation.  This applies to
       the ORM when using query.subquery() as well.
-      
+
     - Fixed missing _label attribute on Function object, others
       when used in a select() with use_labels (such as when used
       in an ORM column_property()).  [ticket:1302]
@@ -3668,7 +3668,7 @@ CHANGES
     - anonymous alias names now truncate down to the max length
       allowed by the dialect.  More significant on DBs like
       Oracle with very small character limits. [ticket:1309]
-      
+
     - the __selectable__() interface has been replaced entirely
       by __clause_element__().
 
@@ -3686,14 +3686,14 @@ CHANGES
       close, will be detected so that no results doesn't
       fail on recent versions of pysqlite which raise 
       an error when fetchone() called with no rows present.
-      
+
 - postgresql
     - Index reflection won't fail when an index with 
       multiple expressions is encountered.
-      
+
     - Added PGUuid and PGBit types to 
       sqlalchemy.databases.postgres. [ticket:1327]
-    
+
     - Refection of unknown PG types won't crash when those
       types are specified within a domain.  [ticket:1327]
 
@@ -3710,20 +3710,20 @@ CHANGES
 
     - Declarative locates the "inherits" class using a search
       through __bases__, to skip over mixins that are local
-      to subclasses.   
-      
+      to subclasses.
+
     - Declarative figures out joined-table inheritance primary join
       condition even if "inherits" mapper argument is given 
       explicitly. 
 
     - Declarative will properly interpret the "foreign_keys" argument
       on a backref() if it's a string.
-      
+
     - Declarative will accept a table-bound column as a property
       when used in conjunction with __table__, if the column is already
       present in __table__.  The column will be remapped to the given 
       key the same way as when added to the mapper() properties dict.
-      
+
 0.5.2
 ======
 
@@ -3747,7 +3747,7 @@ CHANGES
       fully establish instrumentation for subclasses where the mapper
       was created after the superclass had already been fully
       instrumented. [ticket:1292]
-      
+
     - Fixed bug in delete-orphan cascade whereby two one-to-one
       relations from two different parent classes to the same target 
       class would prematurely expunge the instance.
@@ -3756,7 +3756,7 @@ CHANGES
       loading would prevent other eager loads, self referential or not,
       from joining to the parent JOIN properly.  Thanks to Alex K
       for creating a great test case.
-    
+
     - session.expire() and related methods will not expire() unloaded
       deferred attributes.  This prevents them from being needlessly
       loaded when the instance is refreshed.
@@ -3765,7 +3765,7 @@ CHANGES
       construct to the existing left side, even if query.from_self()
       or query.select_from(someselectable) has been called.
       [ticket:1293]
-      
+
 - sql
     - Further fixes to the "percent signs and spaces in column/table
        names" functionality. [ticket:1284]
@@ -3791,7 +3791,7 @@ CHANGES
       Session methods have been deprecated, replaced by 
       "expunge_all()" and "add()".  "expunge_all()" has also
       been added to ScopedSession.
-      
+
     - Modernized the "no mapped table" exception and added a more
       explicit __table__/__tablename__ exception to declarative.
 
@@ -3808,12 +3808,12 @@ CHANGES
 
     - Test coverage added for `relation()` objects specified on
       concrete mappers. [ticket:1237]
-    
+
     - Query.from_self() as well as query.subquery() both disable 
       the rendering of eager joins inside the subquery produced.
       The "disable all eager joins" feature is available publically
       via a new query.enable_eagerloads() generative. [ticket:1276]
-      
+
     - Added a rudimental series of set operations to Query that
       receive Query objects as arguments, including union(),
       union_all(), intersect(), except_(), insertsect_all(),
@@ -3822,7 +3822,7 @@ CHANGES
 
     - Fixed bug that prevented Query.join() and eagerloads from 
       attaching to a query that selected from a union or aliased union.
-      
+
     - A short documentation example added for bidirectional
       relations specified on concrete mappers. [ticket:1237]
 
@@ -3850,17 +3850,17 @@ CHANGES
       behavior with an m2m table, use an explcit association class
       so that the individual association row is treated as a parent.
       [ticket:1281]
-    
+
     - delete-orphan cascade always requires delete cascade.  Specifying
       delete-orphan without delete now raises a deprecation warning.
       [ticket:1281]
-      
+
 - sql
     - Improved the methodology to handling percent signs in column
       names from [ticket:1256].  Added more tests.  MySQL and
       PostgreSQL dialects still do not issue correct CREATE TABLE
       statements for identifiers with percent signs in them.
-      
+
 - schema
     - Index now accepts column-oriented InstrumentedAttributes
       (i.e. column-based mapped class attributes) as column
@@ -3869,16 +3869,16 @@ CHANGES
     - Column with no name (as in declarative) won't raise a 
       NoneType error when it's string output is requsted
       (such as in a stack trace).
-      
+
     - Fixed bug when overriding a Column with a ForeignKey
       on a reflected table, where derived columns (i.e. the 
       "virtual" columns of a select, etc.) would inadvertently
       call upon schema-level cleanup logic intended only
       for the original column. [ticket:1278]
-      
+
 - declarative
     - Can now specify Column objects on subclasses which have no
-      table of their own (i.e. use single table inheritance).  
+      table of their own (i.e. use single table inheritance).
       The columns will be appended to the base table, but only
       mapped by the subclass.
 
@@ -3897,7 +3897,7 @@ CHANGES
 
     - It's an error to add new Column objects to a declarative class
       that specified an existing table using __table__.
-      
+
 - mysql
     - Added the missing keywords from MySQL 4.1 so they get escaped
       properly.
@@ -4542,38 +4542,38 @@ CHANGES
 
     - Added an example illustrating Celko's "nested sets" as a 
       SQLA mapping.
-    
+
     - contains_eager() with an alias argument works even when 
       the alias is embedded in a SELECT, as when sent to the
       Query via query.select_from().
-      
+
     - contains_eager() usage is now compatible with a Query that
       also contains a regular eager load and limit/offset, in that
       the columns are added to the Query-generated subquery.
       [ticket:1180]
-      
+
     - session.execute() will execute a Sequence object passed to
       it (regression from 0.4).
-    
+
     - Removed the "raiseerror" keyword argument from object_mapper()
       and class_mapper().  These functions raise in all cases
       if the given class/instance is not mapped.
 
     - Fixed session.transaction.commit() on a autocommit=False
       session not starting a new transaction.
-      
+
     - Some adjustments to Session.identity_map's weak referencing
       behavior to reduce asynchronous GC side effects.
-    
+
     - Adjustment to Session's post-flush accounting of newly
       "clean" objects to better protect against operating on
       objects as they're asynchronously gc'ed. [ticket:1182]
-    
+
 - sql
     - column.in_(someselect) can now be used as a columns-clause
       expression without the subquery bleeding into the FROM clause
       [ticket:1074]
-      
+
 - sqlite
     - Overhauled SQLite date/time bind/result processing to use
       regular expressions and format strings, rather than
@@ -4585,7 +4585,7 @@ CHANGES
       2.5.0's new requirement that only Python unicode objects are 
       accepted;
       http://itsystementwicklung.de/pipermail/list-pysqlite/2008-March/000018.html
-      
+
 - mysql
     - Temporary tables are now reflectable.
 
@@ -4614,7 +4614,7 @@ CHANGES
       roughly equivalent to first()[0], value()
       takes a single column expression and is roughly equivalent to
       values(expr).next()[0].
-      
+
     - Improved the determination of the FROM clause when placing SQL
       expressions in the query() list of entities.  In particular
       scalar subqueries should not "leak" their inner FROM objects
@@ -4643,12 +4643,12 @@ CHANGES
 
     - query.order_by().get() silently drops the "ORDER BY" from 
       the query issued by GET but does not raise an exception.
-      
+
     - Added a Validator AttributeExtension, as well as a 
       @validates decorator which is used in a similar fashion
       as @reconstructor, and marks a method as validating
       one or more mapped attributes.
-      
+
     - class.someprop.in_() raises NotImplementedError pending the
       implementation of "in_" for relation [ticket:1140]
 
@@ -4658,7 +4658,7 @@ CHANGES
     - Fixed bug whereby deferred() columns with a group in conjunction
       with an otherwise unrelated synonym() would produce 
       an AttributeError during deferred load.
-      
+
     - The before_flush() hook on SessionExtension takes place before
       the list of new/dirty/deleted is calculated for the final
       time, allowing routines within before_flush() to further
@@ -4669,7 +4669,7 @@ CHANGES
       optionally be a list, supporting events sent to multiple
       SessionExtension instances.  Session places SessionExtensions
       in Session.extensions.
-      
+
     - Reentrant calls to flush() raise an error.  This also serves
       as a rudimentary, but not foolproof, check against concurrent
       calls to Session.flush().
@@ -4696,11 +4696,11 @@ CHANGES
     - The 3-tuple of iterables returned by attributes.get_history()
       may now be a mix of lists and tuples.  (Previously members
       were always lists.)
-      
+
     - Fixed bug whereby changing a primary key attribute on an 
       entity where the attribute's previous value had been expired 
       would produce an error upon flush(). [ticket:1151]
-      
+
     - Fixed custom instrumentation bug whereby get_instance_dict()
       was not called for newly constructed instances not loaded
       by the ORM.
@@ -4708,22 +4708,22 @@ CHANGES
     - Session.delete() adds the given object to the session if 
       not already present.  This was a regression bug from 0.4.
       [ticket:1150]
-      
+
     - The `echo_uow` flag on `Session` is deprecated, and unit-of-work
       logging is now application-level only, not per-session level.
 
     - Removed conflicting `contains()` operator from 
       `InstrumentedAttribute` which didn't accept `escape` kwaarg
       [ticket:1153].
-      
+
 - declarative
     - Fixed bug whereby mapper couldn't initialize if a composite
       primary key referenced another table that was not defined
       yet. [ticket:1161]
-    
+
     - Fixed exception throw which would occur when string-based
       primaryjoin condition was used in conjunction with backref.
-      
+
 - schema
     - Added "sorted_tables" accessor to MetaData, which returns
       Table objects sorted in order of dependency as a list.
@@ -4748,33 +4748,33 @@ CHANGES
     - The exists() construct won't "export" its contained list 
       of elements as FROM clauses, allowing them to be used more
       effectively in the columns clause of a SELECT.
-      
+
     - and_() and or_() now generate a ColumnElement, allowing
       boolean expressions as result columns, i.e.
       select([and_(1, 0)]).  [ticket:798]
-    
+
     - Bind params now subclass ColumnElement which allows them to be
       selectable by orm.query (they already had most ColumnElement
       semantics).
-      
+
     - Added select_from() method to exists() construct, which becomes
       more and more compatible with a regular select().
-      
+
     - Added func.min(), func.max(), func.sum() as "generic functions",
       which basically allows for their return type to be determined
       automatically.  Helps with dates on SQLite, decimal types, 
       others. [ticket:1160]
-    
+
     - added decimal.Decimal as an "auto-detect" type; bind parameters
       and generic functions will set their type to Numeric when a 
       Decimal is used.
-      
+
 - mysql
     - The 'length' argument to MSInteger, MSBigInteger, MSTinyInteger,
       MSSmallInteger and MSYear has been renamed to 'display_width'.
-      
+
     - Added MSMediumInteger type [ticket:1146].
-    
+
     - the function func.utc_timestamp() compiles to UTC_TIMESTAMP, without
       the parenthesis, which seem to get in the way when using in 
       conjunction with executemany().
index b69fe3d2ce4f04521b5e66714a94c9b37e7d47d6..1cf9c3588fea45a15ecdf3542e952fd43e2fd4b6 100644 (file)
@@ -15,12 +15,12 @@ Running as a user with permission to modify the Python distribution,
 install Distribute:
 
     python3 distribute_setup.py
-    
+
 
 Installing SQLAlchemy in Python 3
 ---------------------------------
 
-Once Distribute is installed, SQLAlchemy can be installed directly.  
+Once Distribute is installed, SQLAlchemy can be installed directly.
 The 2to3 process will kick in which takes several minutes:
 
     python3 setup.py install
index b9e37db7cbbb392a99711fd8a7c3d8cd8cb1b46f..8e4b9893f12cf9b70918d661bf3cf5e1afb17c7f 100644 (file)
@@ -81,7 +81,7 @@ another database, use the --dburi option with any standard SQLAlchemy URL:
 
     --dburi=postgresql://user:password@localhost/test
 
-Use an empty database and a database user with general DBA privileges.  
+Use an empty database and a database user with general DBA privileges.
 The test suite will be creating and dropping many tables and other DDL, and
 preexisting tables will interfere with the tests.
 
@@ -103,15 +103,15 @@ expect them to be present will fail.
 Additional steps specific to individual databases are as follows:
 
     ORACLE: a user named "test_schema" is created.
-    
+
     The primary database user needs to be able to create and drop tables,
     synonyms, and constraints within the "test_schema" user.   For this
     to work fully, including that the user has the "REFERENCES" role
     in a remote shcema for tables not yet defined (REFERENCES is per-table),
     it is required that the test the user be present in the "DBA" role:
-    
+
         grant dba to scott;
-    
+
     SYBASE: Similar to Oracle, "test_schema" is created as a user, and the
     primary test user needs to have the "sa_role". 
  
@@ -120,7 +120,7 @@ Additional steps specific to individual databases are as follows:
     the transaction log is full otherwise.
 
     A full series of setup assuming sa/master: 
-   
+
         disk init name="translog", physname="/opt/sybase/data/translog.dat", size="10M"
         create database sqlalchemy on default log on translog="10M"
         sp_dboption sqlalchemy, "trunc log on chkpt", true
@@ -142,9 +142,9 @@ Additional steps specific to individual databases are as follows:
     will occur with record locking isolation. This feature is only available
     with MSSQL 2005 and greater. You must enable snapshot isolation at the
     database level and set the default cursor isolation with two SQL commands:
-    
+
      ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
-    
+
      ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON
 
     MSSQL+zxJDBC: Trying to run the unit tests on Windows against SQL Server
index b82480ad3a9e2d91fcba68dd394d3a24d9b6c231..d5feaf85eebc2bed47a4df295657f834a2b0a1c5 100644 (file)
@@ -14,14 +14,14 @@ from mako.template import Template
 class MakoBridge(TemplateBridge):
     def init(self, builder, *args, **kw):
         self.layout = builder.config.html_context.get('mako_layout', 'html')
-        
+
         self.lookup = TemplateLookup(directories=builder.config.templates_path,
             format_exceptions=True, 
             imports=[
                 "from builder import util"
             ]
         )
-        
+
     def render(self, template, context):
         template = template.replace(".html", ".mako")
         context['prevtopic'] = context.pop('prev', None)
@@ -30,8 +30,8 @@ class MakoBridge(TemplateBridge):
         # sphinx 1.0b2 doesn't seem to be providing _ for some reason...
         context.setdefault('_', lambda x:x)
         return self.lookup.get_template(template).render_unicode(**context)
-        
-    
+
+
     def render_string(self, template, context):
         context['prevtopic'] = context.pop('prev', None)
         context['nexttopic'] = context.pop('next', None)
@@ -44,7 +44,7 @@ class MakoBridge(TemplateBridge):
                 "from builder import util"
             ]
         ).render_unicode(**context)
-        
+
 class StripDocTestFilter(Filter):
     def filter(self, lexer, stream):
         for ttype, value in stream:
@@ -116,7 +116,7 @@ def _strip_trailing_whitespace(iter_):
         buf[-1] = (buf[-1][0], buf[-1][1].rstrip())
     for t, v in buf:
         yield t, v
-    
+
 class PopupSQLFormatter(HtmlFormatter):
     def _format_lines(self, tokensource):
         buf = []
@@ -134,7 +134,7 @@ class PopupSQLFormatter(HtmlFormatter):
                     yield 1, "<div class='popup_sql'>%s</div>" % re.sub(r'(?:[{stop}|\n]*)$', '', value)
             else:
                 buf.append((ttype, value))
-        
+
         for t, v in _strip_trailing_whitespace(HtmlFormatter._format_lines(self, iter(buf))):
             yield t, v
 
@@ -148,7 +148,7 @@ class PopupLatexFormatter(LatexFormatter):
                     continue
             else:
                 yield ttype, value
-        
+
     def format(self, tokensource, outfile):
         LatexFormatter.format(self, self._filter_tokens(tokensource), outfile)
 
@@ -164,5 +164,4 @@ def setup(app):
     app.connect('autodoc-skip-member', autodoc_skip_member)
     PygmentsBridge.html_formatter = PopupSQLFormatter
     PygmentsBridge.latex_formatter = PopupLatexFormatter
-    
-    
\ No newline at end of file
+
index dc2e27245a292b320cfcd5ce573de55cc13b8bfa..a9dcff001a3eb0be940aa25b06a3c94630dcd368 100644 (file)
@@ -6,7 +6,7 @@ def striptags(text):
 def go(m):
     # .html with no anchor if present, otherwise "#" for top of page
     return m.group(1) or '#'
-    
+
 def strip_toplevel_anchors(text):
     return re.compile(r'(\.html)?#[-\w]+-toplevel').sub(go, text)
-    
+
index 7591e73e220112f8f5fc7729741642b8c5572220..7b2e6aa69eb2177bcdff2178512df3a272332b8d 100644 (file)
@@ -22,7 +22,7 @@ Recall from :ref:`engines_toplevel` that an :class:`.Engine` is created via
 the :func:`.create_engine` call::
 
     engine = create_engine('mysql://scott:tiger@localhost/test')
-    
+
 The typical usage of :func:`.create_engine()` is once per particular database
 URL, held globally for the lifetime of a single application process. A single
 :class:`.Engine` manages many individual DBAPI connections on behalf of the
@@ -89,7 +89,7 @@ If the :class:`.ResultProxy` potentially has rows remaining, it can be
 instructed to close out its resources explicitly::
 
     result.close()
-    
+
 If the :class:`.ResultProxy` has pending rows remaining and is dereferenced by
 the application without being closed, Python garbage collection will
 ultimately close out the cursor as well as trigger a return of the pooled
@@ -116,7 +116,7 @@ in :ref:`sqlexpression_toplevel`.
 
 .. autoclass:: sqlalchemy.engine.base.ResultProxy
     :members:
-    
+
 .. autoclass:: sqlalchemy.engine.base.RowProxy
     :members:
 
@@ -243,7 +243,7 @@ to use the :meth:`~.Executable.execute` method of
 any :class:`.Executable` construct, which is a marker for SQL expression objects
 that support execution.   The SQL expression object itself references an
 :class:`.Engine` or :class:`.Connection` known as the **bind**, which it uses
-in order to provide so-called "implicit" execution services.  
+in order to provide so-called "implicit" execution services.
 
 Given a table as below::
 
index dbc7dcc451ac2aa730280ebc8b0ab6120517867c..0b5ce345dceda6f50df0a63ba21680ee92db67b4 100644 (file)
@@ -46,9 +46,9 @@ SQLAlchemy dialect always requires that an appropriate DBAPI driver is installed
 The table below summarizes the state of DBAPI support in SQLAlchemy 0.7.  The values 
 translate as:
 
-* yes / Python platform - The SQLAlchemy dialect is mostly or fully operational on the target platform.   
+* yes / Python platform - The SQLAlchemy dialect is mostly or fully operational on the target platform.
 * yes / OS platform - The DBAPI supports that platform.
-* no / Python platform - The DBAPI does not support that platform, or there is no SQLAlchemy dialect support.  
+* no / Python platform - The DBAPI does not support that platform, or there is no SQLAlchemy dialect support.
 * no / OS platform - The DBAPI does not support that platform.
 * partial - the DBAPI is partially usable on the target platform but has major unresolved issues.
 * development - a development version of the dialect exists, but is not yet usable.
@@ -280,7 +280,7 @@ namespace of SA loggers that can be turned on is as follows:
 * ``sqlalchemy.engine`` - controls SQL echoing.  set to ``logging.INFO`` for SQL query output, ``logging.DEBUG`` for query + result set output.
 * ``sqlalchemy.dialects`` - controls custom logging for SQL dialects.  See the documentation of individual dialects for details. 
 * ``sqlalchemy.pool`` - controls connection pool logging.  set to ``logging.INFO`` or lower to log connection pool checkouts/checkins.
-* ``sqlalchemy.orm`` - controls logging of various ORM functions.  set to ``logging.INFO`` for information on mapper configurations.   
+* ``sqlalchemy.orm`` - controls logging of various ORM functions.  set to ``logging.INFO`` for information on mapper configurations.
 
 For example, to log SQL queries using Python logging instead of the ``echo=True`` flag::
 
index f1a428d8ca3a10c5f8ecac1745a3b098e39c4a2b..86cc7d968faf2eaf5fc8361692f327bee0ab689f 100644 (file)
@@ -24,10 +24,10 @@ and that a user-defined listener function should receive two positional argument
 
     from sqlalchemy.event import listen
     from sqlalchemy.pool import Pool
-    
+
     def my_on_connect(dbapi_con, connection_record):
         print "New DBAPI connection:", dbapi_con
-        
+
     listen(Pool, 'connect', my_on_connect)
 
 Targets
@@ -43,13 +43,13 @@ classes and objects::
     from sqlalchemy import create_engine
     from sqlalchemy.engine import Engine
     import psycopg2
-    
+
     def connect():
         return psycopg2.connect(username='ed', host='127.0.0.1', dbname='test')
 
     my_pool = QueuePool(connect)
     my_engine = create_engine('postgresql://ed@localhost/test')
-    
+
     # associate listener with all instances of Pool
     listen(Pool, 'connect', my_on_connect)
 
@@ -73,9 +73,9 @@ which modifies the subsequent handling.   By default, no listener ever requires
 
     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)
@@ -89,7 +89,7 @@ Both SQLAlchemy Core and SQLAlchemy ORM feature a wide variety of event hooks:
   :ref:`core_event_toplevel` and include event hooks specific to
   connection pool lifecycle, SQL statement execution,
   transaction lifecycle, and schema creation and teardown.
-  
+
 * **ORM Events** - these are described in
   :ref:`orm_event_toplevel`, and include event hooks specific to
   class and attribute instrumentation, object initialization
index 1b4a35f84d8d3383bc34f2bfde7729972589ff54..e907b25352f17d943655d170572df125a72ad0b3 100644 (file)
@@ -46,11 +46,11 @@ The expression package uses functions to construct SQL expressions.  The return
 .. autofunction:: extract
 
 .. attribute:: func
-   
+
    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)
 
@@ -58,29 +58,29 @@ The expression package uses functions to construct SQL expressions.  The return
    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)
-        
+
    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`.
-   
+
 .. autofunction:: insert
 
 .. autofunction:: intersect
@@ -179,7 +179,7 @@ Classes
 .. autoclass:: Function
    :members:
    :show-inheritance:
-   
+
 .. autoclass:: FromClause
    :members:
    :show-inheritance:
@@ -220,18 +220,18 @@ Generic Functions
 SQL functions which are known to SQLAlchemy with regards to database-specific
 rendering, return types and argument behavior. Generic functions are invoked
 like all SQL functions, using the :attr:`func` attribute::
-    
+
     select([func.count()]).select_from(sometable)
-    
+
 Note that any name not known to :attr:`func` generates the function name as is
 - there is no restriction on what SQL functions can be called, known or
 unknown to SQLAlchemy, built-in or user defined. The section here only
 describes those functions where SQLAlchemy already knows what argument and
 return types are in use.
-    
+
 .. automodule:: sqlalchemy.sql.functions
    :members:
    :undoc-members:
    :show-inheritance:
-   
-   
+
+
index 6af349322010bcbed48594e9cbfccd399989a858..780016baeb25fef8185736dd274e172124ea461e 100644 (file)
@@ -5,7 +5,7 @@ SQLAlchemy Core
 
 .. toctree::
     :maxdepth: 2
-    
+
     tutorial
     expression_api
     engines
@@ -19,5 +19,4 @@ SQLAlchemy Core
     compiler
     serializer
     interfaces
-    
-    
\ No newline at end of file
+
index c1f99feeb86c5921d754dbd6715f359935035353..3caced3ae72a36a52fe3e3476eaf5ee521b91d1f 100644 (file)
@@ -1217,9 +1217,9 @@ will take over the job of issuing DDL for the constraint. Additionally, the
 constraint will be added via ALTER:
 
 .. sourcecode:: python+sql
-    
+
     from sqlalchemy import event
-    
+
     event.listen(
         users,
         "after_create", 
@@ -1251,7 +1251,7 @@ parameter ``dialect``, which is the string name of a dialect or a tuple of such,
 which will limit the execution of the item to just those dialects.  It also
 accepts a ``callable_`` parameter which may reference a Python callable which will 
 be invoked upon event reception, returning ``True`` or ``False`` indicating if
-the event should proceed.   
+the event should proceed.
 
 If our :class:`~sqlalchemy.schema.CheckConstraint` was only supported by
 Postgresql and not other databases, we could limit its usage to just that dialect::
@@ -1268,7 +1268,7 @@ Postgresql and not other databases, we could limit its usage to just that dialec
     )
 
 Or to any set of dialects::
-    
+
     event.listen(
         users,
         "after_create",
@@ -1332,7 +1332,7 @@ Custom DDL phrases are most easily achieved using the
 other DDL elements except it accepts a string which is the text to be emitted:
 
 .. sourcecode:: python+sql
-    
+
     event.listen(
         metadata,
         "after_create",
index b7d5ba27262102916e0d12a59a8aa780ff136d14..543d57ae25caa726da95e666612f0bc009ac64e9 100644 (file)
@@ -1078,7 +1078,7 @@ Finally, we're back to INSERT for some more detail. The :func:`~sqlalchemy.sql.e
 
     # insert from a function
     users.insert().values(id=12, name=func.upper('jack'))
-    
+
     # insert from a concatenation expression
     addresses.insert().values(email_address = name + '@' + host)
 
@@ -1088,7 +1088,7 @@ Finally, we're back to INSERT for some more detail. The :func:`~sqlalchemy.sql.e
         users.insert().values(name=func.upper('jack')),
         fullname='Jack Jones'
     )
-    
+
 :func:`~sqlalchemy.sql.expression.bindparam` constructs can be passed, however the names of the table's columns are reserved for the "automatic" generation of bind names::
 
     users.insert().values(id=bindparam('_id'), name=bindaparam('_name'))
@@ -1102,7 +1102,7 @@ Finally, we're back to INSERT for some more detail. The :func:`~sqlalchemy.sql.e
             {'_id':3, '_name':'name3'},
         ]
     )
-    
+
 Updates work a lot like INSERTS, except there is an additional WHERE clause that can be specified:
 
 .. sourcecode:: pycon+sql
index 47bbd87d79ccf616ef71b81262fc56afa1f29a7d..d2a56e8e9f28531b4fdfaf50804f6c84035a8125 100644 (file)
@@ -274,17 +274,17 @@ many decimal places.   Here's a recipe that rounds them down::
 
     from sqlalchemy.types import TypeDecorator, Numeric
     from decimal import Decimal
-    
+
     class SafeNumeric(TypeDecorator):
         """Adds quantization to Numeric."""
-    
+
         impl = Numeric
-    
+
         def __init__(self, *arg, **kw):
             TypeDecorator.__init__(self, *arg, **kw)
             self.quantize_int = -(self.impl.precision - self.impl.scale)
             self.quantize = Decimal(10) ** self.quantize_int
-        
+
         def process_bind_param(self, value, dialect):
             if isinstance(value, Decimal) and \
                 value.as_tuple()[2] < self.quantize_int:
@@ -305,10 +305,10 @@ binary in CHAR(16) if desired::
 
     class GUID(TypeDecorator):
         """Platform-independent GUID type.
-    
+
         Uses Postgresql's UUID type, otherwise uses
         CHAR(32), storing as stringified hex values.
-    
+
         """
         impl = CHAR
 
@@ -348,11 +348,11 @@ to/from JSON.   Can be modified to use Python's builtin json encoder::
 
     class JSONEncodedDict(TypeDecorator):
         """Represents an immutable structure as a json-encoded string.
-        
+
         Usage::
-        
+
             JSONEncodedDict(255)
-            
+
         """
 
         impl = VARCHAR
@@ -377,7 +377,7 @@ changes, and combine this using the ``sqlalchemy.ext.mutable`` extension
 described in :ref:`mutable_toplevel`::
 
     from sqlalchemy.ext.mutable import Mutable
-    
+
     class MutationDict(Mutable, dict):
         @classmethod
         def coerce(cls, key, value):
@@ -385,15 +385,15 @@ described in :ref:`mutable_toplevel`::
             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.change()
 
@@ -402,7 +402,7 @@ described in :ref:`mutable_toplevel`::
 
             dict.__delitem__(self, key)
             self.change()
-        
+
         # additional dict methods would be overridden here
 
 The new dictionary type can be associated with JSONEncodedDict using
index 2d75a5c08f7e5e1dc133302bf713000ae5b4ea87..e6442efd0ce8e70bf15ff3e081cfe44e7a718e70 100644 (file)
@@ -3,12 +3,12 @@ Table of Contents
 
 .. toctree::
     :maxdepth: 2
-    
+
     intro
     orm/index
     core/index
     dialects/index
-    
+
 Indices and tables
 ------------------
 
index b679dca3e1a9c6cd6db1e14480aabc7b5db89131..d3409cec38640838fcbb255c7a498e6db6c27268 100644 (file)
@@ -28,7 +28,7 @@ queries.
 Documentation Overview
 ======================
 
-The documentation is separated into three sections: :ref:`orm_toplevel`, :ref:`core_toplevel`, and :ref:`dialect_toplevel`.  
+The documentation is separated into three sections: :ref:`orm_toplevel`, :ref:`core_toplevel`, and :ref:`dialect_toplevel`.
 
 In :ref:`orm_toplevel`, the Object Relational Mapper is introduced and fully
 described. New users should begin with the :ref:`ormtutorial_toplevel`. If you
@@ -71,7 +71,7 @@ this from the command-line:
 .. sourcecode:: none
 
     # easy_install SQLAlchemy
-    
+
 Or with pip:
 
 .. sourcecode:: none
index 7f585fc507b24ace66c732699b846c72ace05e38..98de8e20595851f6e683fd9c5845d2be913c2a0a 100644 (file)
@@ -5,7 +5,7 @@
 Collection Configuration and Techniques
 =======================================
 
-The :func:`.relationship` function defines a linkage between two classes.   
+The :func:`.relationship` function defines a linkage between two classes.
 When the linkage defines a one-to-many or many-to-many relationship, it's
 represented as a Python collection when objects are loaded and manipulated.
 This section presents additional information about collection configuration
@@ -335,21 +335,21 @@ on :class:`.MappedCollection` are already instrumented - calling them
 from within an already instrumented call can cause events to be fired off
 repeatedly, or inappropriately, leading to internal state corruption in
 rare cases::
-    
+
     from sqlalchemy.orm.collections import MappedCollection,\
                                         collection
 
     class MyMappedCollection(MappedCollection):
         """Use @internally_instrumented when your methods 
         call down to already-instrumented methods.
-        
+
         """
-        
+
         @collection.internally_instrumented
         def __setitem__(self, key, value, _sa_initiator=None):
             # do something with key, value
             super(MyMappedCollection, self).__setitem__(key, value, _sa_initiator)
-        
+
         @collection.internally_instrumented
         def __delitem__(self, key, _sa_initiator=None):
             # do something with key
index 4a7ce5dbfea1b0cd8819cf45506e8e9fa6059c7c..c0b99cc5c590bc2895bb5ae4716b902613acfe6a 100644 (file)
@@ -287,7 +287,7 @@ of the ``Holding`` while also giving access to ``.shares``::
 
     session.add(broker)
     session.commit()
-    
+
     # lets take a peek at that holdings_table after committing changes to the db
     print list(holdings_table.select().execute())
     # [(1, 'ZZK', 10), (1, 'JEK', 123), (1, 'STEPZ', 123)]
index 67cd707d8b399eb15ba0ff163fc843192d38d00d..deb97a74cefbaed554905918989ba95ef09bc259 100644 (file)
@@ -8,7 +8,7 @@ API Documentation
 
 .. autoclass:: ShardedSession
    :members:
-   
+
 .. autoclass:: ShardedQuery
    :members:
 
index 9844f9b095f83f7a5762664d341268079ff9b0c6..0b15e7a60f3c69177f68d956bf55509dd8a2e528 100644 (file)
@@ -10,7 +10,7 @@ API Reference
 
 .. autoclass:: Mutable
     :members:
-    
+
 .. autoclass:: MutableComposite
     :members:
 
index af6b0c365ec8058c44c64f79992c531bd3ba0f7f..b17fe75475d3bb86c039c0adb7edf470c72af6c9 100644 (file)
@@ -5,7 +5,7 @@ SQLAlchemy ORM
 
 .. toctree::
     :maxdepth: 2
-    
+
     tutorial
     mapper_config
     relationships
@@ -19,5 +19,4 @@ SQLAlchemy ORM
     extensions/index
     examples
     interfaces
-    
-    
\ No newline at end of file
+
index 65bcd06f95c8aadbc83f92c7832ec4e8cd034b6f..ff932f0f3431796ec425a3d20c3e288173f5b376 100644 (file)
@@ -261,7 +261,7 @@ what's specified in the :meth:`.Session.query`, :meth:`.Query.filter`, or
 :meth:`.Query.select_from` methods::
 
     session.query(Manager.manager_data).select_from(manager)
-    
+
     session.query(engineer.c.id).filter(engineer.c.engineer_info==manager.c.manager_data)
 
 Creating Joins to Specific Subtypes
@@ -530,17 +530,17 @@ to the parent:
                     with_polymorphic=('*', pjoin), 
                     polymorphic_on=pjoin.c.type, 
                     polymorphic_identity='employee')
-                    
+
     mapper(Manager, managers_table, 
                     inherits=employee_mapper, 
                     concrete=True, 
                     polymorphic_identity='manager')
-                    
+
     mapper(Engineer, engineers_table, 
                     inherits=employee_mapper, 
                     concrete=True, 
                     polymorphic_identity='engineer')
-                    
+
     mapper(Company, companies, properties={
         'employees': relationship(Employee)
     })
index afe4ff6b64c5f5a5fcc416088d9d6a9332b41a76..e2fc9f6dd349d5b415a28a3e1b4d0ca8acdbd2a6 100644 (file)
@@ -7,7 +7,7 @@ Relationship Loading Techniques
 
 A big part of SQLAlchemy is providing a wide range of control over how related objects get loaded when querying.   This behavior
 can be configured at mapper construction time using the ``lazy`` parameter to the :func:`.relationship` function,
-as well as by using options with the :class:`.Query` object.   
+as well as by using options with the :class:`.Query` object.
 
 Using Loader Strategies: Lazy Loading, Eager Loading
 ----------------------------------------------------
@@ -59,7 +59,7 @@ additional SQL statement for each collection requested, aggregated across all
 parent objects:
 
 .. sourcecode:: python+sql
-    
+
     {sql}>>>jack = session.query(User).options(subqueryload('addresses')).filter_by(name='jack').all() 
     SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, 
     users.password AS users_password 
@@ -187,7 +187,7 @@ references a scalar many-to-one reference.
  * When using the default lazy loading, if you load 100 objects, and then access a collection on each of
    them, a total of 101 SQL statements will be emitted, although each statement will typically be a
    simple SELECT without any joins.
-   
+
  * When using joined loading, the load of 100 objects and their collections will emit only one SQL
    statement.  However, the 
    total number of rows fetched will be equal to the sum of the size of all the collections, plus one 
@@ -197,16 +197,16 @@ references a scalar many-to-one reference.
    exceptions) will transmit the full data of each parent over the wire to the client connection in 
    any case.  Therefore joined eager loading only makes sense when the size of the collections are 
    relatively small.  The LEFT OUTER JOIN can also be performance intensive compared to an INNER join.
-   
+
  * When using subquery loading, the load of 100 objects will emit two SQL statements.  The second
    statement will fetch a total number of rows equal to the sum of the size of all collections.  An
    INNER JOIN is used, and a minimum of parent columns are requested, only the primary keys.  So a 
    subquery load makes sense when the collections are larger.
-   
+
  * When multiple levels of depth are used with joined or subquery loading, loading collections-within-
    collections will multiply the total number of rows fetched in a cartesian fashion.  Both forms
    of eager loading always join from the original parent class.
-   
+
 * Many to One Reference
 
  * When using the default lazy loading, a load of 100 objects will like in the case of the collection
@@ -216,15 +216,15 @@ references a scalar many-to-one reference.
    if the collection of objects references a relatively small set of target objects, or the full set
    of possible target objects have already been loaded into the session and are strongly referenced,
    using the default of `lazy='select'` is by far the most efficient way to go.
-  
+
  * When using joined loading, the load of 100 objects will emit only one SQL statement.   The join
-   will be a LEFT OUTER JOIN, and the total number of rows will be equal to 100 in all cases.  
+   will be a LEFT OUTER JOIN, and the total number of rows will be equal to 100 in all cases.
    If you know that each parent definitely has a child (i.e. the foreign
    key reference is NOT NULL), the joined load can be configured with ``innerjoin=True``, which is
    usually specified within the :func:`~sqlalchemy.orm.relationship`.   For a load of objects where
    there are many possible target references which may have not been loaded already, joined loading
    with an INNER JOIN is extremely efficient.
-   
+
  * Subquery loading will issue a second load for all the child objects, so for a load of 100 objects
    there would be two SQL statements emitted.  There's probably not much advantage here over
    joined loading, however, except perhaps that subquery loading can use an INNER JOIN in all cases
index 4c57b8c457615079a4305bb4519c9d1a4073dd39..7c0641147c784a0902387a0c3842af5cea5094d3 100644 (file)
@@ -15,7 +15,7 @@ Note that all patterns here apply both to the usage of explicit
 takes a form such as::
 
     mapper(User, users_table, primary_key=[users_table.c.id])
-    
+
 Would translate into declarative as::
 
     class User(Base):
@@ -29,9 +29,9 @@ with the class definition. These are usable as is within ``__mapper_args__``::
 
     class User(Base):
         __tablename__ = 'users'
-        
+
         id = Column(Integer)
-        
+
         __mapper_args__ = {
             'primary_key':[id]
         }
@@ -52,7 +52,7 @@ use the ``include_properties`` or ``exclude_properties`` arguments. For
 example::
 
     mapper(User, users_table, include_properties=['user_id', 'user_name'])
-    
+
 ...will map the ``User`` class to the ``users_table`` table, only including
 the "user_id" and "user_name" columns - the rest are not refererenced.
 Similarly::
@@ -106,7 +106,7 @@ using the desired attribute name in the class definition::
 
     from sqlalchemy.ext.declarative import declarative_base
     Base = declarative_base()
-    
+
     class User(Base):
         __tablename__ = 'user'
         id = Column('user_id', Integer, primary_key=True)
@@ -130,7 +130,7 @@ key relationship or join condition into the same mapped attribute, put them
 together using a list, as below where we map to a :func:`~.expression.join`::
 
     from sqlalchemy.sql import join
-    
+
     # join users and addresses
     usersaddresses = join(users_table, addresses_table, \
         users_table.c.user_id == addresses_table.c.user_id)
@@ -152,21 +152,21 @@ usually invoked implicitly for each mapped :class:`.Column`.  Explicit usage
 looks like::
 
     from sqlalchemy.orm import mapper, column_property
-    
+
     mapper(User, users, properties={
         'name':column_property(users.c.name, active_history=True)
     })
 
 or with declarative::
-    
+
     class User(Base):
         __tablename__ = 'users'
-        
+
         id = Column(Integer, primary_key=True)
         name = column_property(Column(String(50)), active_history=True)
 
 Further examples of :func:`.column_property` are at :ref:`mapper_sql_expressions`.
-        
+
 .. autofunction:: column_property
 
 .. _deferred:
@@ -204,7 +204,7 @@ With declarative, :class:`.Column` objects can be declared directly inside of :f
 
     class Book(Base):
         __tablename__ = 'books'
-        
+
         book_id = Column(Integer, primary_key=True)
         title = Column(String(200), nullable=False)
         summary = Column(String(2000))
@@ -273,7 +273,7 @@ scalar-returning
 used.  Unlike older versions of SQLAlchemy, there is no :func:`~.sql.expression.label` requirement::
 
     from sqlalchemy.orm import column_property
-    
+
     mapper(User, users_table, properties={
         'fullname': column_property(
             users_table.c.firstname + " " + users_table.c.lastname
@@ -284,7 +284,7 @@ Correlated subqueries may be used as well::
 
     from sqlalchemy.orm import column_property
     from sqlalchemy import select, func
-    
+
     mapper(User, users_table, properties={
         'address_count': column_property(
                 select([func.count(addresses_table.c.address_id)]).\
@@ -305,7 +305,7 @@ loaded::
         @property
         def fullname(self):
             return self.firstname + " " + self.lastname
-            
+
 To invoke a SQL statement from an instance that's already been loaded, the
 session associated with the instance can be acquired using
 :func:`~.session.object_session` which will provide the appropriate
@@ -313,7 +313,7 @@ transactional context from which to emit a statement::
 
     from sqlalchemy.orm import object_session
     from sqlalchemy import select, func
-    
+
     class User(object):
         @property
         def address_count(self):
@@ -343,9 +343,9 @@ attribute extensions, are only called by normal userland code; they are not
 issued when the ORM is populating the object.
 
 .. sourcecode:: python+sql
-    
+
     from sqlalchemy.orm import validates
-    
+
     addresses_table = Table('addresses', metadata,
         Column('id', Integer, primary_key=True),
         Column('email', String)
@@ -383,11 +383,11 @@ plain descriptor, and to have it read/write from a mapped attribute with a
 different name. Below we illustrate this using Python 2.6-style properties::
 
     class EmailAddress(object):
-        
+
         @property
         def email(self):
             return self._email
-            
+
         @email.setter
         def email(self, email):
             self._email = email
@@ -456,7 +456,7 @@ do case-insensitive comparison::
 
     from sqlalchemy.orm.properties import ColumnProperty
     from sqlalchemy.sql import func
-    
+
     class MyComparator(ColumnProperty.Comparator):
         def __eq__(self, other):
             return func.lower(self.__clause_element__()) == func.lower(other)
@@ -496,13 +496,13 @@ class you provide.
     As of SQLAlchemy 0.7, composites are implemented as a simple wrapper using
     the :ref:`hybrids_toplevel` feature.   Note that composites no longer
     "conceal" the underlying colunm based attributes, or support in-place 
-    mutation.  
+    mutation.
 
-A simple example represents pairs of columns as a "Point" object.  
+A simple example represents pairs of columns as a "Point" object.
 Starting with a table that represents two points as x1/y1 and x2/y2::
 
     from sqlalchemy import Table, Column
-    
+
     vertices = Table('vertices', metadata,
         Column('id', Integer, primary_key=True),
         Column('x1', Integer),
@@ -597,7 +597,7 @@ passed in to a mapper as the table.
 
     from sqlalchemy.orm import mapper
     from sqlalchemy.sql import join
-    
+
     class AddressUser(object):
         pass
 
@@ -614,7 +614,7 @@ Note that the list of columns is equivalent to the usage of :func:`.column_prope
 with multiple columns::
 
     from sqlalchemy.orm import mapper, column_property
-    
+
     mapper(AddressUser, j, properties={
         'user_id': column_property(users_table.c.user_id, addresses_table.c.user_id)
     })
@@ -624,12 +624,12 @@ to multiple columns, since the declarative class parser won't recognize a plain
 list of columns::
 
     from sqlalchemy.ext.declarative import declarative_base
-    
+
     Base = declarative_base()
-    
+
     class AddressUser(Base):
         __table__ = j
-        
+
         user_id = column_property(users_table.c.user_id, addresses_table.c.user_id)
 
 A second example::
index f9337a5f63957e3269636773bccaf4eb714fa2ce..a4ac63ee7ae06764ab8433194bf6bd1e2d0a0b54 100644 (file)
@@ -63,20 +63,20 @@ To establish a bi-directional relationship in one-to-many, where the "reverse" s
 ``Child`` will get a ``parent`` attribute with many-to-one semantics.
 
 Declarative::
-    
+
     from sqlalchemy.ext.declarative import declarative_base
     Base = declarative_base()
-    
+
     class Parent(Base):
         __tablename__ = 'parent'
         id = Column(Integer, primary_key=True)
         children = relationship("Child", backref="parent")
-        
+
     class Child(Base):
         __tablename__ = 'child'
         id = Column(Integer, primary_key=True)
         parent_id = Column(Integer, ForeignKey('parent.id'))
-        
+
 
 Many To One
 ~~~~~~~~~~~~
@@ -125,7 +125,7 @@ Declarative::
         id = Column(Integer, primary_key=True)
         child_id = Column(Integer, ForeignKey('child.id'))
         child = relationship("Child", backref="parents")
-        
+
     class Child(Base):
         __tablename__ = 'child'
         id = Column(Integer, primary_key=True)
@@ -150,14 +150,14 @@ of the relationship. To convert one-to-many into one-to-one::
     mapper(Parent, parent_table, properties={
         'child': relationship(Child, uselist=False, backref='parent')
     })
-    
+
     mapper(Child, child_table)
 
 Or to turn a one-to-many backref into one-to-one, use the :func:`.backref` function
 to provide arguments for the reverse side::
-    
+
     from sqlalchemy.orm import backref
-    
+
     parent_table = Table('parent', metadata,
         Column('id', Integer, primary_key=True),
         Column('child_id', Integer, ForeignKey('child.id'))
@@ -183,11 +183,11 @@ The second example above as declarative::
         id = Column(Integer, primary_key=True)
         child_id = Column(Integer, ForeignKey('child.id'))
         child = relationship("Child", backref=backref("parent", uselist=False))
-        
+
     class Child(Base):
         __tablename__ = 'child'
         id = Column(Integer, primary_key=True)
-    
+
 Many To Many
 ~~~~~~~~~~~~~
 
@@ -238,18 +238,18 @@ plain schematic form::
         Column('left_id', Integer, ForeignKey('left.id')),
         Column('right_id', Integer, ForeignKey('right.id'))
     )
-    
+
     class Parent(Base):
         __tablename__ = 'left'
         id = Column(Integer, primary_key=True)
         children = relationship("Child", 
                         secondary=association_table, 
                         backref="parents")
-        
+
     class Child(Base):
         __tablename__ = 'right'
         id = Column(Integer, primary_key=True)
-    
+
 .. _association_pattern:
 
 Association Object
@@ -313,16 +313,16 @@ Declarative::
         left_id = Column(Integer, ForeignKey('left.id'), primary_key=True)
         right_id = Column(Integer, ForeignKey('right.id'), primary_key=True)
         child = relationship("Child", backref="parent_assocs")
-        
+
     class Parent(Base):
         __tablename__ = 'left'
         id = Column(Integer, primary_key=True)
         children = relationship(Association, backref="parent")
-        
+
     class Child(Base):
         __tablename__ = 'right'
         id = Column(Integer, primary_key=True)
-        
+
 Working with the association pattern in its direct form requires that child
 objects are associated with an association instance before being appended to
 the parent; similarly, access from parent to child goes through the
@@ -442,7 +442,7 @@ when the collection is only one column)::
 
     from sqlalchemy.ext.declarative import declarative_base
     Base = declarative_base()
-    
+
     class Node(Base):
         __tablename__ = 'nodes'
         id = Column(Integer, primary_key=True)
@@ -451,7 +451,7 @@ when the collection is only one column)::
         children = relationship("Node", 
                         backref=backref('parent', remote_side=id)
                     )
-        
+
 There are several examples included with SQLAlchemy illustrating
 self-referential strategies; these include :ref:`examples_adjacencylist` and
 :ref:`examples_xmlpersistence`.
@@ -761,7 +761,7 @@ A typical mutable primary key setup might look like:
 
     # passive_updates=False *only* needed if the database
     # does not implement ON UPDATE CASCADE
-    
+
     mapper(User, users, properties={
         'addresses': relationship(Address, passive_updates=False)
     })
index d08ce5f5a970bd852663e9cb50da7b84ace5068c..7e0c8bb83b62c7cbf5729791a968840480733ced 100644 (file)
@@ -91,10 +91,10 @@ to acquire connection resources.   This association can
 be set up as in the example above, using the ``bind`` argument.   You 
 can also associate a :class:`.Engine` with an existing :func:`.sessionmaker` 
 using the :meth:`.sessionmaker.configure` method::
-    
+
     from sqlalchemy.orm import sessionmaker
     from sqlalchemy import create_engine
-    
+
     # configure Session class with desired options
     Session = sessionmaker()
 
@@ -111,7 +111,7 @@ you can also associate individual :class:`.Session` objects with an :class:`.Eng
 on each invocation::
 
     session = Session(bind=engine)
-    
+
 ...or directly with a :class:`.Connection`::
 
     conn = engine.connect()
@@ -167,12 +167,12 @@ Frequently Asked Questions
     that point on your other modules say "from mypackage import Session". That
     way, everyone else just uses :class:`.Session()`,
     and the configuration of that session is controlled by that central point.
-    
+
     If your application starts up, does imports, but does not know what
     database it's going to be connecting to, you can bind the
     :class:`.Session` at the "class" level to the
     engine later on, using ``configure()``.
-    
+
     In the examples in this section, we will frequently show the
     :func:`.sessionmaker` being created right above the line where we actually
     invoke :class:`~sqlalchemy.orm.session.Session()`. But that's just for
@@ -189,7 +189,7 @@ Frequently Asked Questions
     then remains in use for the lifespan of a particular database
     conversation, which includes not just the initial loading of objects but
     throughout the whole usage of those instances.
-    
+
     Objects become detached if their owning session is discarded. They are
     still functional in the detached state if the user has ensured that their
     state has not been expired before detachment, but they will not be able to
@@ -197,14 +197,14 @@ Frequently Asked Questions
     to consider persisted objects as an extension of the state of a particular
     :class:`.Session`, and to keep that session around until all referenced
     objects have been discarded.
-    
+
     An exception to this is when objects are placed in caches or otherwise
     shared among threads or processes, in which case their detached state can
     be stored, transmitted, or shared. However, the state of detached objects
     should still be transferred back into a new :class:`.Session` using
     :meth:`.Session.add` or :meth:`.Session.merge` before working with the
     object (or in the case of merge, its state) again.
-    
+
     It is also very common that a :class:`.Session` as well as its associated
     objects are only referenced by a single thread.  Sharing objects between
     threads is most safely accomplished by sharing their state among multiple
@@ -212,7 +212,7 @@ Frequently Asked Questions
     :class:`.Session` per thread, :meth:`.Session.merge` to transfer state
     between threads.   This pattern is not a strict requirement by any means, 
     but it has the least chance of introducing concurrency issues.
-    
+
     To help with the recommended :class:`.Session` -per-thread,
     :class:`.Session` -per-set-of-objects patterns, the
     :func:`.scoped_session` function is provided which produces a
@@ -233,10 +233,10 @@ Frequently Asked Questions
     map and see that the object is already there. It's only when you say
     ``query.get({some primary key})`` that the
     :class:`~sqlalchemy.orm.session.Session` doesn't have to issue a query.
-    
+
     Additionally, the Session stores object instances using a weak reference
     by default. This also defeats the purpose of using the Session as a cache.
-    
+
     The :class:`.Session` is not designed to be a
     global object from which everyone consults as a "registry" of objects.
     That's more the job of a **second level cache**.   SQLAlchemy provides
@@ -278,7 +278,7 @@ Frequently Asked Questions
     sharing the session with those threads, but you also will have implemented
     a proper locking scheme (or your graphical framework does) so that those
     threads do not collide.
-    
+
     A multithreaded application is usually going to want to make usage of
     :func:`.scoped_session` to transparently manage sessions per thread.
     More on this at :ref:`unitofwork_contextual`.
@@ -416,33 +416,33 @@ Merge Tips
 
 :meth:`~.Session.merge` is an extremely useful method for many purposes.  However,
 it deals with the intricate border between objects that are transient/detached and
-those that are persistent, as well as the automated transferrence of state.  
+those that are persistent, as well as the automated transferrence of state.
 The wide variety of scenarios that can present themselves here often require a
 more careful approach to the state of objects.   Common problems with merge usually involve 
-some unexpected state regarding the object being passed to :meth:`~.Session.merge`.   
+some unexpected state regarding the object being passed to :meth:`~.Session.merge`.
 
 Lets use the canonical example of the User and Address objects::
 
     class User(Base):
         __tablename__ = 'user'
-    
+
         id = Column(Integer, primary_key=True)
         name = Column(String(50), nullable=False)
         addresses = relationship("Address", backref="user")
-    
+
     class Address(Base):
         __tablename__ = 'address'
 
         id = Column(Integer, primary_key=True)
         email_address = Column(String(50), nullable=False)
         user_id = Column(Integer, ForeignKey('user.id'), nullable=False)
-        
+
 Assume a ``User`` object with one ``Address``, already persistent::
 
     >>> u1 = User(name='ed', addresses=[Address(email_address='ed@ed.com')])
     >>> session.add(u1)
     >>> session.commit()
-    
+
 We now create ``a1``, an object outside the session, which we'd like
 to merge on top of the existing ``Address``::
 
@@ -450,7 +450,7 @@ to merge on top of the existing ``Address``::
     >>> a1 = Address(id=existing_a1.id)
 
 A surprise would occur if we said this::
-    
+
     >>> a1.user = u1
     >>> a1 = session.merge(a1)
     >>> session.commit()
@@ -508,7 +508,7 @@ is equivalent to::
     >>> existing_a1.id = existing_a1.id
     >>> existing_a1.user_id = u1.id
     >>> existing_a1.user = None
-    
+
 Where above, both ``user_id`` and ``user`` are assigned to, and change events
 are emitted for both.  The ``user`` association
 takes precedence, and None is applied to ``user_id``, causing a failure.
@@ -517,11 +517,11 @@ Most :meth:`~.Session.merge` issues can be examined by first checking -
 is the object prematurely in the session ? 
 
 .. sourcecode:: python+sql
-    
+
     >>> a1 = Address(id=existing_a1, user_id=user.id)
     >>> assert a1 not in session
     >>> a1 = session.merge(a1)
-    
+
 Or is there state on the object that we don't want ?   Examining ``__dict__``
 is a quick way to check::
 
@@ -537,7 +537,7 @@ is a quick way to check::
     >>> a1 = session.merge(a1)
     >>> # success
     >>> session.commit()
-    
+
 Deleting
 --------
 
@@ -900,14 +900,14 @@ place::
     >>> session.add(o1)
     >>> o1 in session
     True
-    
+
     >>> i1 = Item()
     >>> i1.order = o1
     >>> i1 in o1.orders
     True
     >>> i1 in session
     True
-    
+
 This behavior can be disabled as of 0.6.5 using the ``cascade_backrefs`` flag::
 
     mapper(Order, order_table, properties={
@@ -1241,7 +1241,7 @@ entire database interaction is rolled back::
     from sqlalchemy.orm import sessionmaker
     from sqlalchemy import create_engine
     from unittest import TestCase
-    
+
     # global application scope.  create Session class, engine
     Session = sessionmaker()
 
@@ -1254,23 +1254,23 @@ entire database interaction is rolled back::
 
             # begin a non-ORM transaction
             self.trans = connection.begin()
-    
+
             # bind an individual Session to the connection
             self.session = Session(bind=self.connection)
-    
+
         def test_something(self):
-            # use the session in tests.   
-            
+            # use the session in tests.
+
             self.session.add(Foo())
             self.session.commit()
-    
+
         def tearDown(self):
             # rollback - everything that happened with the
             # Session above (including calls to commit()) 
             # is rolled back.
             self.trans.rollback()
             self.session.close()
-            
+
 Above, we issue :meth:`.Session.commit` as well as
 :meth:`.Transaction.rollback`. This is an example of where we take advantage
 of the :class:`.Connection` object's ability to maintain *subtransactions*, or
@@ -1414,7 +1414,7 @@ Contextual Session API
 
 .. autoclass:: sqlalchemy.util.ScopedRegistry
     :members:
-    
+
 .. autoclass:: sqlalchemy.util.ThreadLocalRegistry
 
 .. _session_partitioning:
@@ -1490,7 +1490,7 @@ those described in :ref:`events_orm_toplevel`.
 
 .. autoclass:: History
     :members:
-    
+
 .. attribute:: sqlalchemy.orm.attributes.PASSIVE_NO_INITIALIZE
 
    Symbol indicating that loader callables should
index b0a4b24c2475307e2e95d03e7d4a1098b7a457fb..2dedf704965831e27497913af634fa3dbb5c8d93 100644 (file)
@@ -185,10 +185,10 @@ Creating Table, Class and Mapper All at Once Declaratively
 The preceding approach to configuration involved a
 :class:`~sqlalchemy.schema.Table`, a user-defined class, and
 a call to :func:`~.orm.mapper`.  This illustrates classical SQLAlchemy usage, which values
-the highest separation of concerns possible.  
+the highest separation of concerns possible.
 A large number of applications don't require this degree of
 separation, and for those SQLAlchemy offers an alternate "shorthand"
-configurational style called :mod:`~.sqlalchemy.ext.declarative`.  
+configurational style called :mod:`~.sqlalchemy.ext.declarative`.
 For many applications, this is the only style of configuration needed.
 Our above example using this style is as follows:: 
 
@@ -1440,7 +1440,7 @@ completely and start again.
     >>> session.close()  # roll back and close the transaction
     >>> from sqlalchemy.orm import clear_mappers
     >>> clear_mappers() # remove all class mappings
-    
+
 
 Below, we use :class:`~.orm.mapper` to reconfigure an ORM mapping for ``User`` and
 ``Address``, on our existing but currently un-mapped classes. The
index 23513dbbad153296bfda28033853cafaa878c3f6..697837e9478ec213c18d789b36470248f34c502a 100644 (file)
@@ -86,7 +86,7 @@ h1 {
     font: normal 20px/22px arial,helvetica,sans-serif;
     color: #222;
     padding:0px;
-    margin:0px;   
+    margin:0px;
 }
 
 .topnav h2 {
@@ -94,7 +94,7 @@ h1 {
     font-family:arial,helvetica,sans-serif;
     font-size:1.6em;
     font-weight:normal;
-    line-height:1.6em;  
+    line-height:1.6em;
 }
 
 .topnav h3 {
@@ -185,7 +185,7 @@ div.admonition .admonition-title {
 }
 
 .totoc {
-    
+
 }
 
 .doc_copyright {
index bdb699a660514d46f2fb428f0332f5b7a5bd8fff..b8f776dd260277ad81f20fafc9ed7c75d4fcac62 100644 (file)
@@ -30,7 +30,7 @@
     % else:
         ${entryname|h}
     % endif
-    
+
     % if subitems:
   <dd><dl>
     % for subentryname, subentrylinks in subitems:
index d842fdd63c85ea7c5d2725f30be78b21773c8ed3..879818efa76d0a93686f89f363cfb15644002f22 100644 (file)
         <div class="topnav">
             <div id="pagecontrol">
                 <a href="${pathto('genindex')}">Index</a>
-            
+
                 % if sourcename:
                 <div class="sourcelink">(<a href="${pathto('_sources/' + sourcename, True)|h}">${_('view source')})</div>
                 % endif
             </div>
-            
+
             <div class="navbanner">
                 <a class="totoc" href="${pathto(master_doc)}">Table of Contents</a>
                 % if parents:
@@ -74,7 +74,7 @@
                 % if current_page_name != master_doc:
                 Â» ${self.show_title()} 
                 % endif
-                
+
                 ${prevnext()}
                 <h2>
                     ${self.show_title()} 
@@ -85,7 +85,7 @@
             % endif
             <div class="clearboth"></div>
         </div>
-        
+
         <div class="document">
             <div class="body">
                 ${next.body()}
index 6242398699dd452e7607edc028bc6db0a7cc3f12..bac43f09711fb2320f048a4b9264e436bc6285d5 100644 (file)
@@ -1,9 +1,9 @@
 from sqlalchemy import MetaData, Table, Column, Sequence, ForeignKey,\
                         Integer, String, create_engine
-                        
+
 from sqlalchemy.orm import sessionmaker, mapper, relationship, backref,\
                                 joinedload_all
-                                
+
 from sqlalchemy.orm.collections import attribute_mapped_collection
 
 metadata = MetaData()
@@ -18,38 +18,38 @@ class TreeNode(object):
     def __init__(self, name, parent=None):
         self.name = name
         self.parent = parent
-        
+
     def append(self, nodename):
         self.children[nodename] = TreeNode(nodename, parent=self)
-    
+
     def __repr__(self):
         return "TreeNode(name=%r, id=%r, parent_id=%r)" % (
                     self.name,
                     self.id,
                     self.parent_id
                 )
-                
+
 def dump_tree(node, indent=0):
-    
+
     return "   " * indent + repr(node) + \
                 "\n" + \
                 "".join([
                     dump_tree(c, indent +1) 
                     for c in node.children.values()]
                 )
-                    
+
 
 mapper(TreeNode, tree_table, properties={
     'children': relationship(TreeNode, 
 
                         # cascade deletions
                         cascade="all",
-    
+
                         # many to one + adjacency list - remote_side
                         # is required to reference the 'remote' 
                         # column in the join condition.
                         backref=backref("parent", remote_side=tree_table.c.id),
-                         
+
                         # children will be represented as a dictionary
                         # on the "name" attribute.
                         collection_class=attribute_mapped_collection('name'),
index d3d7641678bbf51d93ddbdf79f8e48a56a15ce7f..19b304f9a5e905483524134ec39f3ec8ef63e731 100644 (file)
@@ -60,7 +60,7 @@ class OrderItem(object):
     def __init__(self, item, price=None):
         self.item = item
         self.price = price or item.price
-        
+
 mapper(Order, orders, properties={
     'order_items': relationship(OrderItem, cascade="all, delete-orphan",
                             backref='order')
@@ -82,7 +82,7 @@ session.commit()
 # function to return items from the DB
 def item(name):
     return session.query(Item).filter_by(description=name).one()
-    
+
 # create an order
 order = Order('john smith')
 
index d7e97efea272f42cad8380a11ba16944c8a0d8de..cc9f71d8b8c0a76c4cb2c7e9b53510660acf157c 100644 (file)
@@ -16,17 +16,17 @@ In this demo, the following techniques are illustrated:
   deep within an object graph when lazy loads occur.
 
 E.g.::
-    
+
     # query for Person objects, specifying cache
     q = Session.query(Person).options(FromCache("default", "all_people"))
-    
+
     # specify that each Person's "addresses" collection comes from
     # cache too
     q = q.options(RelationshipCache("default", "by_person", Person.addresses))
-    
+
     # query
     print q.all()
-    
+
 To run, both SQLAlchemy and Beaker (1.4 or greater) must be
 installed or on the current PYTHONPATH. The demo will create a local
 directory for datafiles, insert initial data, and run. Running the
@@ -53,7 +53,7 @@ Listing of files:
     bootstrap fixture data if necessary.
 
     caching_query.py - Represent functions and classes 
-    which allow the usage of Beaker caching with SQLAlchemy.  
+    which allow the usage of Beaker caching with SQLAlchemy.
     Introduces a query option called FromCache.
 
     model.py - The datamodel, which represents Person that has multiple
index 11306003365648987cbb583b42b382098ff3dd17..c16e02f33a0300cc08e0ab310792713a1d5f2795 100644 (file)
@@ -13,13 +13,13 @@ from sqlalchemy.orm import joinedload
 
 def load_name_range(start, end, invalidate=False):
     """Load Person objects on a range of names.
-    
+
     start/end are integers, range is then
     "person <start>" - "person <end>".
-    
+
     The cache option we set up is called "name_range", indicating 
     a range of names for the Person class.
-    
+
     The `Person.addresses` collections are also cached.  Its basically
     another level of tuning here, as that particular cache option
     can be transparently replaced with joinedload(Person.addresses). 
@@ -36,17 +36,17 @@ def load_name_range(start, end, invalidate=False):
     # have the "addresses" collection cached separately
     # each lazyload of Person.addresses loads from cache.
     q = q.options(RelationshipCache("default", "by_person", Person.addresses))
-    
+
     # alternatively, eagerly load the "addresses" collection, so that they'd
     # be cached together.   This issues a bigger SQL statement and caches
     # a single, larger value in the cache per person rather than two
     # separate ones.
     #q = q.options(joinedload(Person.addresses))
-    
+
     # if requested, invalidate the cache on current criterion.
     if invalidate:
         q.invalidate()
-        
+
     return q.all()
 
 print "two through twelve, possibly from cache:\n"
index d9ec1576ebeca79ed3ee3eee9e69114457d77b3d..4af812500f35a18bded13e65c0a6ba9060ecb324 100644 (file)
@@ -16,7 +16,7 @@ The three new concepts introduced here are:
 
 The rest of what's here are standard SQLAlchemy and
 Beaker constructs.
-   
+
 """
 from sqlalchemy.orm.interfaces import MapperOption
 from sqlalchemy.orm.query import Query
@@ -25,10 +25,10 @@ from sqlalchemy.sql import visitors
 class CachingQuery(Query):
     """A Query subclass which optionally loads full results from a Beaker 
     cache region.
-    
+
     The CachingQuery stores additional state that allows it to consult
     a Beaker cache before accessing the database:
-    
+
     * A "region", which is a cache region argument passed to a 
       Beaker CacheManager, specifies a particular cache configuration
       (including backend implementation, expiration times, etc.)
@@ -36,13 +36,13 @@ class CachingQuery(Query):
       group of keys within the cache.  A query that filters on a name 
       might use the name "by_name", a query that filters on a date range 
       to a joined table might use the name "related_date_range".
-      
+
     When the above state is present, a Beaker cache is retrieved.
-    
+
     The "namespace" name is first concatenated with 
     a string composed of the individual entities and columns the Query 
     requests, i.e. such as ``Query(User.id, User.name)``.
-    
+
     The Beaker cache is then loaded from the cache manager based
     on the region and composed namespace.  The key within the cache
     itself is then constructed against the bind parameters specified
@@ -51,17 +51,17 @@ class CachingQuery(Query):
 
     The FromCache and RelationshipCache mapper options below represent
     the "public" method of configuring this state upon the CachingQuery.
-    
+
     """
-    
+
     def __init__(self, manager, *args, **kw):
         self.cache_manager = manager
         Query.__init__(self, *args, **kw)
-        
+
     def __iter__(self):
         """override __iter__ to pull results from Beaker
            if particular attributes have been configured.
-           
+
            Note that this approach does *not* detach the loaded objects from
            the current session. If the cache backend is an in-process cache
            (like "memory") and lives beyond the scope of the current session's
@@ -69,7 +69,7 @@ class CachingQuery(Query):
            modified to first expunge() each loaded item from the current
            session before returning the list of items, so that the items
            in the cache are not the same ones in the current Session.
-           
+
         """
         if hasattr(self, '_cache_parameters'):
             return self.get_value(createfunc=lambda: list(Query.__iter__(self)))
@@ -99,13 +99,13 @@ class CachingQuery(Query):
         """Set the value in the cache for this query."""
 
         cache, cache_key = _get_cache_parameters(self)
-        cache.put(cache_key, value)        
+        cache.put(cache_key, value)
 
 def query_callable(manager):
     def query(*arg, **kw):
         return CachingQuery(manager, *arg, **kw)
     return query
-    
+
 def _get_cache_parameters(query):
     """For a query with cache_region and cache_namespace configured,
     return the correspoinding Cache instance and cache key, based
@@ -116,16 +116,16 @@ def _get_cache_parameters(query):
         raise ValueError("This Query does not have caching parameters configured.")
 
     region, namespace, cache_key = query._cache_parameters
-    
+
     namespace = _namespace_from_query(namespace, query)
-    
+
     if cache_key is None:
         # cache key - the value arguments from this query's parameters.
         args = _params_from_query(query)
         cache_key = " ".join([str(x) for x in args])
-    
+
     assert cache_key is not None, "Cache key was None !"
-    
+
     # get cache
     cache = query.cache_manager.get_cache_region(namespace, region)
 
@@ -146,7 +146,7 @@ def _namespace_from_query(namespace, query):
     return namespace
 
 def _set_cache_parameters(query, region, namespace, cache_key):
-    
+
     if hasattr(query, '_cache_parameters'):
         region, namespace, cache_key = query._cache_parameters
         raise ValueError("This query is already configured "
@@ -154,7 +154,7 @@ def _set_cache_parameters(query, region, namespace, cache_key):
                         (region, namespace)
                     )
     query._cache_parameters = region, namespace, cache_key
-    
+
 class FromCache(MapperOption):
     """Specifies that a Query should load results from a cache."""
 
@@ -162,14 +162,14 @@ class FromCache(MapperOption):
 
     def __init__(self, region, namespace, cache_key=None):
         """Construct a new FromCache.
-        
+
         :param region: the cache region.  Should be a
         region configured in the Beaker CacheManager.
-        
+
         :param namespace: the cache namespace.  Should
         be a name uniquely describing the target Query's
         lexical structure.
-        
+
         :param cache_key: optional.  A string cache key 
         that will serve as the key to the query.   Use this
         if your query has a huge amount of parameters (such
@@ -180,10 +180,10 @@ class FromCache(MapperOption):
         self.region = region
         self.namespace = namespace
         self.cache_key = cache_key
-    
+
     def process_query(self, query):
         """Process a Query during normal loading operation."""
-        
+
         _set_cache_parameters(query, self.region, self.namespace, self.cache_key)
 
 class RelationshipCache(MapperOption):
@@ -194,18 +194,18 @@ class RelationshipCache(MapperOption):
 
     def __init__(self, region, namespace, attribute):
         """Construct a new RelationshipCache.
-        
+
         :param region: the cache region.  Should be a
         region configured in the Beaker CacheManager.
-        
+
         :param namespace: the cache namespace.  Should
         be a name uniquely describing the target Query's
         lexical structure.
-        
+
         :param attribute: A Class.attribute which
         indicates a particular class relationship() whose
         lazy loader should be pulled from the cache.
-        
+
         """
         self.region = region
         self.namespace = namespace
@@ -234,11 +234,11 @@ class RelationshipCache(MapperOption):
 
     def and_(self, option):
         """Chain another RelationshipCache option to this one.
-        
+
         While many RelationshipCache objects can be specified on a single
         Query separately, chaining them together allows for a more efficient
         lookup during load.
-        
+
         """
         self._relationship_options.update(option._relationship_options)
         return self
@@ -246,18 +246,18 @@ class RelationshipCache(MapperOption):
 
 def _params_from_query(query):
     """Pull the bind parameter values from a query.
-    
+
     This takes into account any scalar attribute bindparam set up.
-    
+
     E.g. params_from_query(query.filter(Cls.foo==5).filter(Cls.bar==7)))
     would return [5, 7].
-    
+
     """
     v = []
     def visit_bindparam(bind):
-        
+
         if bind.key in query._params:
-            value = query._params[bind.key]    
+            value = query._params[bind.key]
         elif bind.callable:
             # lazyloader may dig a callable in here, intended
             # to late-evaluate params after autoflush is called.
@@ -265,7 +265,7 @@ def _params_from_query(query):
             value = bind.callable()
         else:
             value = bind.value
-        
+
         v.append(value)
     if query._criterion is not None:
         visitors.traverse(query._criterion, {}, {'bindparam':visit_bindparam})
index ea946606ca5e415ff7b25ab72cb11a4d3895ded1..740c5977acd28bfbe147168bbfbe526cc4ec5949 100644 (file)
@@ -35,7 +35,7 @@ if not os.path.exists(root):
                 "Press enter to continue.\n" % root
                 )
     os.makedirs(root)
-    
+
 dbfile = os.path.join(root, "beaker_demo.db")
 engine = create_engine('sqlite:///%s' % dbfile, echo=True)
 Session.configure(bind=engine)
@@ -50,7 +50,7 @@ cache_manager.regions['default'] ={
         'type':'file',
         'data_dir':root,
         'expire':3600,
-        
+
         # set start_time to current time
         # to re-cache everything
         # upon application startup
index 67af746e380071478e6afcc8f83b85be7e4b9689..09f020cea8be0b241ade7f6534482047f787175c 100644 (file)
@@ -19,7 +19,7 @@ def install():
         ('New York', 'United States', ('10001', '10002', '10003', '10004', '10005', '10006')),
         ('San Francisco', 'United States', ('94102', '94103', '94104', '94105', '94107', '94108'))
     ]
-    
+
     countries = {}
     all_post_codes = []
     for city, country, postcodes in data:
@@ -27,12 +27,12 @@ def install():
             country = countries[country]
         except KeyError:
             countries[country] = country = Country(country)
-            
+
         city = City(city, country)
         pc = [PostalCode(code, city) for code in postcodes]
         Session.add_all(pc)
         all_post_codes.extend(pc)
-    
+
     for i in xrange(1, 51):
         person = Person(
                     "person %.2d" % i,
@@ -44,6 +44,6 @@ def install():
         Session.add(person)
 
     Session.commit()
-    
+
     # start the demo fresh
     Session.remove()
\ No newline at end of file
index cce2835f1e826f1190cedd36ab46adcff1501cea..b63858362666547a069067f8cad0ff98a76bb1cd 100644 (file)
@@ -17,7 +17,7 @@ class ScopedSessionNamespace(container.MemoryNamespaceManager):
 
     When used with the query_cache system, the effect is that the objects
     in the cache are the same as that within the session - the merge()
-    is a formality that doesn't actually create a second instance.  
+    is a formality that doesn't actually create a second instance.
     This makes it safe to use for updates of data from an identity
     perspective (still not ideal for deletes though).
 
@@ -25,25 +25,25 @@ class ScopedSessionNamespace(container.MemoryNamespaceManager):
     is automatically disposed upon session.remove().
 
     """
-    
+
     def __init__(self, namespace, scoped_session, **kwargs):
         """__init__ is called by Beaker itself."""
-        
+
         container.NamespaceManager.__init__(self, namespace)
         self.scoped_session = scoped_session
-    
+
     @classmethod
     def create_session_container(cls, beaker_name, scoped_session):
         """Create a new session container for a given scoped_session."""
-        
+
         def create_namespace(namespace, **kw):
             return cls(namespace, scoped_session, **kw)
         cache.clsmap[beaker_name] = create_namespace
-        
+
     @property
     def dictionary(self):
         """Return the cache dictionary used by this MemoryNamespaceManager."""
-        
+
         sess = self.scoped_session()
         try:
             nscache = sess._beaker_cache
@@ -55,35 +55,35 @@ class ScopedSessionNamespace(container.MemoryNamespaceManager):
 if __name__ == '__main__':
     from environment import Session, cache_manager
     from caching_query import FromCache
-    
+
     # create a Beaker container type called "ext:local_session".
     # it will reference the ScopedSession in meta.
     ScopedSessionNamespace.create_session_container("ext:local_session", Session)
-    
+
     # set up a region based on this new container type.
     cache_manager.regions['local_session'] ={'type':'ext:local_session'}
-    
+
     from model import Person
-    
+
     # query to load Person by name, with criterion
     # of "person 10"
     q = Session.query(Person).\
                     options(FromCache("local_session", "by_name")).\
                     filter(Person.name=="person 10")
-                    
+
     # load from DB
     person10 = q.one()
-    
+
     # next call, the query is cached.
     person10 = q.one()
 
     # clear out the Session.  The "_beaker_cache" dictionary
     # disappears with it.
     Session.remove()
-    
+
     # query calls from DB again
     person10 = q.one()
-    
+
     # identity is preserved - person10 is the *same* object that's
     # ultimately inside the cache.   So it is safe to manipulate
     # the not-queried-for attributes of objects when using such a 
index c139d3284c177c96f9692ece9b1fc238215ef678..629b263a795702deb22dd9ba7a7486c980d57d95 100644 (file)
@@ -18,7 +18,7 @@ class Country(Base):
 
     id = Column(Integer, primary_key=True)
     name = Column(String(100), nullable=False)
-    
+
     def __init__(self, name):
         self.name = name
 
@@ -41,15 +41,15 @@ class PostalCode(Base):
     code = Column(String(10), nullable=False)
     city_id = Column(Integer, ForeignKey('city.id'), nullable=False)
     city = relationship(City)
-    
+
     @property
     def country(self):
         return self.city.country
-        
+
     def __init__(self, code, city):
         self.code = code
         self.city = city
-    
+
 class Address(Base):
     __tablename__ = 'address'
 
@@ -58,21 +58,21 @@ class Address(Base):
     street = Column(String(200), nullable=False)
     postal_code_id = Column(Integer, ForeignKey('postal_code.id'))
     postal_code = relationship(PostalCode)
-    
+
     @property
     def city(self):
         return self.postal_code.city
-        
+
     @property
     def country(self):
         return self.postal_code.country
-    
+
     def __str__(self):
         return "%s\t"\
               "%s, %s\t"\
               "%s" % (self.street, self.city.name, 
                 self.postal_code.code, self.country.name)
-        
+
 class Person(Base):
     __tablename__ = 'person'
 
@@ -86,13 +86,13 @@ class Person(Base):
 
     def __str__(self):
         return self.name
-    
+
     def __repr__(self):
         return "Person(name=%r)" % self.name
-        
+
     def format_full(self):
         return "\t".join([str(x) for x in [self] + list(self.addresses)])
-        
+
 # Caching options.   A set of three RelationshipCache options
 # which can be applied to Query(), causing the "lazy load"
 # of these attributes to be loaded from cache.
index 2e2689140cef5ef56c5330f110679c1628bc78fe..644d512cf749c4de60b988bb2c854c782619afb3 100644 (file)
@@ -87,7 +87,7 @@ class MyClass(object):
 
 class MyCollectionAdapter(object):
     """An wholly alternative instrumentation implementation."""
-    
+
     def __init__(self, key, state, collection):
         self.key = key
         self.state = state
index 2899f7fb100472b912e02e179a3763a5dc906c7c..80a33c0d8af735558794ccef436f1bb928f87306 100644 (file)
@@ -28,21 +28,21 @@ if __name__ == '__main__':
     from sqlalchemy.ext.declarative import declarative_base
 
     class Base(object):
-        
+
         def receive_change_event(self, verb, key, value, oldvalue):
             s = "Value '%s' %s on attribute '%s', " % (value, verb, key)
             if oldvalue:
                 s += "which replaced the value '%s', " % oldvalue
             s += "on object %s" % self
             print s
-            
+
     Base = declarative_base(cls=Base)
 
     event.listen(Base, 'attribute_instrument', configure_listener)
 
     class MyMappedClass(Base):
         __tablename__ = "mytable"
-    
+
         id = Column(Integer, primary_key=True)
         data = Column(String(50))
         related_id = Column(Integer, ForeignKey("related.id"))
@@ -50,7 +50,7 @@ if __name__ == '__main__':
 
         def __str__(self):
             return "MyMappedClass(data=%r)" % self.data
-            
+
     class Related(Base):
         __tablename__ = "related"
 
@@ -59,12 +59,12 @@ if __name__ == '__main__':
 
         def __str__(self):
             return "Related(data=%r)" % self.data
-    
+
     # classes are instrumented.  Demonstrate the events !
-    
+
     m1 = MyMappedClass(data='m1', related=Related(data='r1'))
     m1.data = 'm1mod'
     m1.related.mapped.append(MyMappedClass(data='m2'))
     del m1.data
-    
-    
+
+
index 8d15fce0bafbf53ab2df91e86b231ef05ec5ffd0..725d65619de95c4d22d3a0b8be1b25204a60c888 100644 (file)
@@ -4,15 +4,15 @@ class ProxyDict(object):
         self.collection_name = collection_name\r
         self.childclass = childclass\r
         self.keyname = keyname\r
-    \r
+\r
     @property\r
     def collection(self):\r
         return getattr(self.parent, self.collection_name)\r
-    \r
+\r
     def keys(self):\r
         descriptor = getattr(self.childclass, self.keyname)\r
         return [x[0] for x in self.collection.values(descriptor)]\r
-        \r
+\r
     def __getitem__(self, key):\r
         x = self.collection.filter_by(**{self.keyname:key}).first()\r
         if x:\r
@@ -40,11 +40,11 @@ class Parent(Base):
     id = Column(Integer, primary_key=True)\r
     name = Column(String(50))\r
     _collection = relationship("Child", lazy="dynamic", cascade="all, delete-orphan")\r
-    \r
+\r
     @property\r
     def child_map(self):\r
         return ProxyDict(self, '_collection', Child, 'key')\r
-    \r
+\r
 class Child(Base):\r
     __tablename__ = 'child'\r
     id = Column(Integer, primary_key=True)\r
@@ -53,7 +53,7 @@ class Child(Base):
 \r
     def __repr__(self):\r
         return "Child(key=%r)" % self.key\r
-    \r
+\r
 Base.metadata.create_all()\r
 \r
 sess = sessionmaker()()\r
index 33805c0cb17b4da3fcfbc1a8c6f6dd5db8731776..8d47f4aceae28cab2f6341cdfa2c10e1ee91dbe6 100644 (file)
@@ -21,15 +21,15 @@ In order of complexity:
   the load in a non-recursive fashion and is much more efficient.
 
 E.g.::
-    
+
     # parse an XML file and persist in the database
     doc = ElementTree.parse("test.xml")
     session.add(Document(file, doc))
     session.commit()
-    
+
     # locate documents with a certain path/attribute structure 
     for document in find_document('/somefile/header/field2[@attr=foo]'):
         # dump the XML
         print document
-    
+
 """
\ No newline at end of file
index d6110a132bcac94128b63c459d523fcc98968ce7..102f6c37391b601093e9630048b80b25e4ba0dce 100644 (file)
@@ -18,8 +18,8 @@ e = create_engine('sqlite://', echo=True)
 meta = MetaData()
 
 ####################### PART II - Table Metadata #############################
-    
-# stores a top level record of an XML document.  
+
+# stores a top level record of an XML document.
 documents = Table('documents', meta,
     Column('document_id', Integer, primary_key=True),
     Column('filename', String(30), unique=True),
@@ -48,12 +48,12 @@ meta.create_all(e)
 ########################### PART III - Model #################################
 
 # our document class.  contains a string name,
-# and the ElementTree root element.  
+# and the ElementTree root element.
 class Document(object):
     def __init__(self, name, element):
         self.filename = name
         self.element = element
-        
+
     def __str__(self):
         buf = StringIO.StringIO()
         self.element.write(buf)
@@ -101,10 +101,10 @@ class ElementTreeMarshal(object):
     def __get__(self, document, owner):
         if document is None:
             return self
-            
+
         if hasattr(document, '_element'):
             return document._element
-        
+
         nodes = {}
         root = None
         for node in document._nodes:
@@ -120,10 +120,10 @@ class ElementTreeMarshal(object):
                 elem.attrib[attr.name] = attr.value
             elem.text = node.text
             elem.tail = node.tail
-            
+
         document._element = ElementTree.ElementTree(root)
         return document._element
-    
+
     def __set__(self, document, element):
         def traverse(node):
             n = _Node()
@@ -137,7 +137,7 @@ class ElementTreeMarshal(object):
 
         traverse(element.getroot())
         document._element = element
-    
+
     def __delete__(self, document):
         del document._element
         document._nodes = []
index 5e53e6798a05864fafbd0af87a9a7f1692191c5f..28bee4672a6237f03df3ad29b3c5451fd113510c 100644 (file)
@@ -22,7 +22,7 @@ meta = MetaData()
 def are_elements_equal(x, y):
     return x == y
 
-# stores a top level record of an XML document.  
+# stores a top level record of an XML document.
 # the "element" column will store the ElementTree document as a BLOB.
 documents = Table('documents', meta,
     Column('document_id', Integer, primary_key=True),
@@ -33,7 +33,7 @@ documents = Table('documents', meta,
 meta.create_all(e)
 
 # our document class.  contains a string name,
-# and the ElementTree root element.  
+# and the ElementTree root element.
 class Document(object):
     def __init__(self, name, element):
         self.filename = name
@@ -47,7 +47,7 @@ mapper(Document, documents)
 # get ElementTree document
 filename = os.path.join(os.path.dirname(__file__), "test.xml")
 doc = ElementTree.parse(filename)
-    
+
 # save to DB
 session = Session(e)
 session.add(Document("test.xml", doc))
index 6052c68bcb14815ca99894e1693ba2b4a24e24e9..3ba602f00202d2ef1903ca451a5a2c1c2177a1c3 100644 (file)
@@ -9,20 +9,20 @@ Base = declarative_base()
 
 class Node(Base):
     __tablename__ = 'node'
-    
+
     node_id = Column(Integer, primary_key=True)
 
     def __init__(self, id):
         self.node_id = id
-        
+
     def add_neighbors(self, *nodes):
         for node in nodes:
             Edge(self, node)
         return self
-        
+
     def higher_neighbors(self):
         return [x.higher_node for x in self.lower_edges]
-        
+
     def lower_neighbors(self):
         return [x.lower_node for x in self.higher_edges]
 
@@ -32,7 +32,7 @@ class Edge(Base):
     lower_id = Column(Integer, 
                         ForeignKey('node.node_id'), 
                         primary_key=True)
-                        
+
     higher_id = Column(Integer, 
                         ForeignKey('node.node_id'), 
                         primary_key=True)
@@ -43,7 +43,7 @@ class Edge(Base):
     higher_node = relationship(Node,
                                 primaryjoin=higher_id==Node.node_id, 
                                 backref='higher_edges')
-    
+
     # here we have lower.node_id <= higher.node_id
     def __init__(self, n1, n2):
         if n1.node_id < n2.node_id:
@@ -62,7 +62,7 @@ session = sessionmaker(engine)()
 #       n1 -> n2 -> n5
 #                -> n7
 #          -> n3 -> n6
-                
+
 n1 = Node(1)
 n2 = Node(2)
 n3 = Node(3)
index eb832a55d9fe2b4467897c17d41051d96f533714..84fc79cd5edd1da72b3871bdeffad11838228eba 100644 (file)
@@ -25,7 +25,7 @@ class Employee(object):
         self.name = name
     def __repr__(self):
         return self.__class__.__name__ + " " + self.name
-        
+
 class Manager(Employee):
     def __init__(self, name, manager_data):
         self.name = name
@@ -33,7 +33,7 @@ class Manager(Employee):
     def __repr__(self):
         return self.__class__.__name__ + " " + \
                     self.name + " " +  self.manager_data
-    
+
 class Engineer(Employee):
     def __init__(self, name, engineer_info):
         self.name = name
index 87c2de10e3e781d138fd79180efa64271a3ac5c4..316671bed539d25bb851d835bc8748552e87e83c 100644 (file)
@@ -20,7 +20,7 @@ people = Table('people', metadata,
    Column('company_id', Integer, ForeignKey('companies.company_id')),
    Column('name', String(50)),
    Column('type', String(30)))
-   
+
 engineers = Table('engineers', metadata, 
    Column('person_id', Integer, ForeignKey('people.person_id'), 
                                     primary_key=True),
@@ -28,14 +28,14 @@ engineers = Table('engineers', metadata,
    Column('engineer_name', String(50)),
    Column('primary_language', String(50)),
   )
-   
+
 managers = Table('managers', metadata, 
    Column('person_id', Integer, ForeignKey('people.person_id'), 
                                     primary_key=True),
    Column('status', String(30)),
    Column('manager_name', String(50))
    )
-   
+
 # create our classes.  The Engineer and Manager classes extend from Person.
 class Person(object):
     def __init__(self, **kwargs):
index b8ade43ba48fe56b0bbf863a3c1cabc25358f540..a251861d6fde8a377fe0180efbb4f405bffb7d34 100644 (file)
@@ -10,18 +10,18 @@ org_table = Table('organizations', meta,
     Column('org_id', Integer, primary_key=True),
     Column('org_name', String(50), nullable=False, key='name'),
     mysql_engine='InnoDB')
-    
+
 member_table = Table('members', meta,
     Column('member_id', Integer, primary_key=True),
     Column('member_name', String(50), nullable=False, key='name'),
     Column('org_id', Integer, ForeignKey('organizations.org_id', ondelete="CASCADE")),
     mysql_engine='InnoDB')
-    
-    
+
+
 class Organization(object):
     def __init__(self, name):
         self.name = name
-    
+
 class Member(object):
     def __init__(self, name):
         self.name = name
@@ -31,11 +31,11 @@ mapper(Organization, org_table, properties = {
         # Organization.members will be a Query object - no loading
         # of the entire collection occurs unless requested
         lazy="dynamic", 
-        
+
         # Member objects "belong" to their parent, are deleted when 
         # removed from the collection
         cascade="all, delete-orphan",
-        
+
         # "delete, delete-orphan" cascade does not load in objects on delete,
         # allows ON DELETE CASCADE to handle it.
         # this only works with a database that supports ON DELETE CASCADE - 
@@ -49,7 +49,7 @@ mapper(Member, member_table)
 if __name__ == '__main__':
     engine = create_engine("mysql://scott:tiger@localhost/test", echo=True)
     meta.create_all(engine)
-    
+
     # expire_on_commit=False means the session contents
     # will not get invalidated after commit.
     sess = sessionmaker(engine, expire_on_commit=False)()
@@ -86,9 +86,9 @@ if __name__ == '__main__':
     sess.delete(org)
     print "-------------------------\nflush three - delete org, delete members in one statement\n"
     sess.commit()
-    
+
     print "-------------------------\nno Member rows should remain:\n"
     print sess.query(Member).count()
-    
+
     print "------------------------\ndone.  dropping tables."
     meta.drop_all(engine)
\ No newline at end of file
index fbb481759021affa738ed4641e812667c905a1bd..55d734d4ed0fc71baa55ad49dec11976cd0614bd 100644 (file)
@@ -22,7 +22,7 @@ class NestedSetExtension(MapperExtension):
             right_most_sibling = connection.scalar(
                 select([personnel.c.rgt]).where(personnel.c.emp==instance.parent.emp)
             )
-            
+
             connection.execute(
                 personnel.update(personnel.c.rgt>=right_most_sibling).values(
                     lft = case(
@@ -41,21 +41,21 @@ class NestedSetExtension(MapperExtension):
     # before_update() would be needed to support moving of nodes
     # after_delete() would be needed to support removal of nodes.
     # [ticket:1172] needs to be implemented for deletion to work as well.
-    
+
 class Employee(Base):
     __tablename__ = 'personnel'
     __mapper_args__ = {
         'extension':NestedSetExtension(), 
         'batch':False  # allows extension to fire for each instance before going to the next.
     }
-    
+
     parent = None
-    
+
     emp = Column(String, primary_key=True)
-    
+
     left = Column("lft", Integer, nullable=False)
     right = Column("rgt", Integer, nullable=False)
-    
+
     def __repr__(self):
         return "Employee(%s, %d, %d)" % (self.emp, self.left, self.right)
 
@@ -100,4 +100,4 @@ for indentation, employee in session.query(func.count(Employee.emp).label('inden
     group_by(ealias.emp).\
     order_by(ealias.left):
     print "    " * indentation + str(employee)
-    
+
index aaa182df0a78c28b4c38647056241d5ae6b508ac..b674e1eb86ac86084c4f543e5f27d20a571dcb17 100644 (file)
@@ -53,12 +53,12 @@ def association(cls, table):
                     setattr(self, attr_name, GenericAssoc(table.name))
                 getattr(self, attr_name).targets = [value]
             setattr(cls, name, property(get, set))
-    
+
     @property
     def member(self):
         return getattr(self.association, 
                     '_backref_%s' % self.association.type)
-        
+
     setattr(cls, 'member', member)
 
     mapper(GenericAssoc, association_table, properties={
index 1a351f7ae0c8f45895402a943730abe678f15f3f..3eb4ed3bcbdee0d41be328c0362540bb8d9026f2 100644 (file)
@@ -7,20 +7,20 @@ The example illustrates:
 
 * a DDL extension which allows CREATE/DROP to work in 
   conjunction with AddGeometryColumn/DropGeometryColumn
-  
+
 * a Geometry type, as well as a few subtypes, which
   convert result row values to a GIS-aware object,
   and also integrates with the DDL extension.
 
 * a GIS-aware object which stores a raw geometry value
   and provides a factory for functions such as AsText().
-  
+
 * an ORM comparator which can override standard column
   methods on mapped objects to produce GIS operators.
-  
+
 * an attribute event listener that intercepts strings
   and converts to GeomFromText().
-  
+
 * a standalone operator example.
 
 The implementation is limited to only public, well known
index d3f728293f25647e7b0acd1b1d1ef1ca311dd157..68f5ecae953897282c307cf70a2831e3807c39ca 100644 (file)
@@ -24,18 +24,18 @@ class GisElement(object):
 
 class PersistentGisElement(GisElement):
     """Represents a Geometry value as loaded from the database."""
-    
+
     def __init__(self, desc):
         self.desc = desc
 
 class TextualGisElement(GisElement, expression.Function):
     """Represents a Geometry value as expressed within application code; i.e. in wkt format.
-    
+
     Extends expression.Function so that the value is interpreted as 
     GeomFromText(value) in a SQL expression context.
-    
+
     """
-    
+
     def __init__(self, desc, srid=-1):
         assert isinstance(desc, basestring)
         self.desc = desc
@@ -46,17 +46,17 @@ class TextualGisElement(GisElement, expression.Function):
 
 class Geometry(TypeEngine):
     """Base PostGIS Geometry column type.
-    
+
     Converts bind/result values to/from a PersistentGisElement.
-    
+
     """
-    
+
     name = 'GEOMETRY'
-    
+
     def __init__(self, dimension=None, srid=-1):
         self.dimension = dimension
         self.srid = srid
-    
+
     def bind_processor(self, dialect):
         def process(value):
             if value is not None:
@@ -64,7 +64,7 @@ class Geometry(TypeEngine):
             else:
                 return value
         return process
-        
+
     def result_processor(self, dialect, coltype):
         def process(value):
             if value is not None:
@@ -78,10 +78,10 @@ class Geometry(TypeEngine):
 
 class Point(Geometry):
     name = 'POINT'
-    
+
 class Curve(Geometry):
     name = 'CURVE'
-    
+
 class LineString(Curve):
     name = 'LINESTRING'
 
@@ -93,36 +93,36 @@ class LineString(Curve):
 class GISDDL(object):
     """A DDL extension which integrates SQLAlchemy table create/drop 
     methods with PostGis' AddGeometryColumn/DropGeometryColumn functions.
-    
+
     Usage::
-    
+
         sometable = Table('sometable', metadata, ...)
-        
+
         GISDDL(sometable)
 
         sometable.create()
-    
+
     """
-    
+
     def __init__(self, table):
         for event in ('before-create', 'after-create', 'before-drop', 'after-drop'):
             table.ddl_listeners[event].append(self)
         self._stack = []
-        
+
     def __call__(self, event, table, bind):
         if event in ('before-create', 'before-drop'):
             regular_cols = [c for c in table.c if not isinstance(c.type, Geometry)]
             gis_cols = set(table.c).difference(regular_cols)
             self._stack.append(table.c)
             table._columns = expression.ColumnCollection(*regular_cols)
-            
+
             if event == 'before-drop':
                 for c in gis_cols:
                     bind.execute(select([func.DropGeometryColumn('public', table.name, c.name)], autocommit=True))
-                
+
         elif event == 'after-create':
             table._columns = self._stack.pop()
-            
+
             for c in table.c:
                 if isinstance(c.type, Geometry):
                     bind.execute(select([func.AddGeometryColumn(table.name, c.name, c.type.srid, c.type.name, c.type.dimension)], autocommit=True))
@@ -133,7 +133,7 @@ class GISDDL(object):
 
 def _to_postgis(value):
     """Interpret a value as a GIS-compatible construct."""
-    
+
     if hasattr(value, '__clause_element__'):
         return value.__clause_element__()
     elif isinstance(value, (expression.ClauseElement, GisElement)):
@@ -149,18 +149,18 @@ def _to_postgis(value):
 class GisAttribute(AttributeExtension):
     """Intercepts 'set' events on a mapped instance attribute and 
     converts the incoming value to a GIS expression.
-    
+
     """
-    
+
     def set(self, state, value, oldvalue, initiator):
         return _to_postgis(value)
-            
+
 class GisComparator(ColumnProperty.ColumnComparator):
     """Intercepts standard Column operators on mapped class attributes
     and overrides their behavior.
-    
+
     """
-    
+
     # override the __eq__() operator
     def __eq__(self, other):
         return self.__clause_element__().op('~=')(_to_postgis(other))
@@ -168,19 +168,19 @@ class GisComparator(ColumnProperty.ColumnComparator):
     # add a custom operator
     def intersects(self, other):
         return self.__clause_element__().op('&&')(_to_postgis(other))
-        
+
     # any number of GIS operators can be overridden/added here
     # using the techniques above.
-        
+
 
 def GISColumn(*args, **kw):
     """Define a declarative column property with GIS behavior.
-    
+
     This just produces orm.column_property() with the appropriate
     extension and comparator_factory arguments.  The given arguments
     are passed through to Column.  The declarative module extracts
     the Column for inclusion in the mapped table.
-    
+
     """
     return column_property(
                 Column(*args, **kw), 
@@ -201,21 +201,21 @@ if __name__ == '__main__':
 
     class Road(Base):
         __tablename__ = 'roads'
-        
+
         road_id = Column(Integer, primary_key=True)
         road_name = Column(String)
         road_geom = GISColumn(Geometry(2))
-    
+
     # enable the DDL extension, which allows CREATE/DROP operations
     # to work correctly.  This is not needed if working with externally
-    # defined tables.    
+    # defined tables.
     GISDDL(Road.__table__)
 
     metadata.drop_all()
     metadata.create_all()
 
     session = sessionmaker(bind=engine)()
-    
+
     # Add objects.  We can use strings...
     session.add_all([
         Road(road_name='Jeff Rd', road_geom='LINESTRING(191232 243118,191108 243242)'),
@@ -224,30 +224,30 @@ if __name__ == '__main__':
         Road(road_name='Graeme Ave', road_geom='LINESTRING(189412 252431,189631 259122)'),
         Road(road_name='Phil Tce', road_geom='LINESTRING(190131 224148,190871 228134)'),
     ])
-    
+
     # or use an explicit TextualGisElement (similar to saying func.GeomFromText())
     r = Road(road_name='Dave Cres', road_geom=TextualGisElement('LINESTRING(198231 263418,198213 268322)', -1))
     session.add(r)
-    
+
     # pre flush, the TextualGisElement represents the string we sent.
     assert str(r.road_geom) == 'LINESTRING(198231 263418,198213 268322)'
     assert session.scalar(r.road_geom.wkt) == 'LINESTRING(198231 263418,198213 268322)'
-    
+
     session.commit()
 
     # after flush and/or commit, all the TextualGisElements become PersistentGisElements.
     assert str(r.road_geom) == "01020000000200000000000000B832084100000000E813104100000000283208410000000088601041"
-    
+
     r1 = session.query(Road).filter(Road.road_name=='Graeme Ave').one()
-    
+
     # illustrate the overridden __eq__() operator.
-    
+
     # strings come in as TextualGisElements
     r2 = session.query(Road).filter(Road.road_geom == 'LINESTRING(189412 252431,189631 259122)').one()
-    
+
     # PersistentGisElements work directly
     r3 = session.query(Road).filter(Road.road_geom == r1.road_geom).one()
-    
+
     assert r1 is r2 is r3
 
     # illustrate the "intersects" operator
@@ -256,7 +256,7 @@ if __name__ == '__main__':
     # illustrate usage of the "wkt" accessor. this requires a DB
     # execution to call the AsText() function so we keep this explicit.
     assert session.scalar(r1.road_geom.wkt) == 'LINESTRING(189412 252431,189631 259122)'
-    
+
     session.rollback()
-    
+
     metadata.drop_all()
index 6b4813dd33d98e58d68fcfab523f273b684d65f1..9f1157c32b3cbfe07595930587833f77f840d7d8 100644 (file)
@@ -74,12 +74,12 @@ weather_reports = Table("weather_reports", meta,
 for db in (db1, db2, db3, db4):
     meta.drop_all(db)
     meta.create_all(db)
-    
+
 # establish initial "id" in db1
 db1.execute(ids.insert(), nextid=1)
 
 
-# step 5. define sharding functions.  
+# step 5. define sharding functions.
 
 # we'll use a straight mapping of a particular set of "country" 
 # attributes to shard id.
@@ -92,12 +92,12 @@ shard_lookup = {
 
 def shard_chooser(mapper, instance, clause=None):
     """shard chooser.
-    
+
     looks at the given instance and returns a shard id
     note that we need to define conditions for 
     the WeatherLocation class, as well as our secondary Report class which will
     point back to its WeatherLocation via its 'location' attribute.
-    
+
     """
     if isinstance(instance, WeatherLocation):
         return shard_lookup[instance.continent]
@@ -105,24 +105,24 @@ def shard_chooser(mapper, instance, clause=None):
         return shard_chooser(mapper, instance.location)
 
 def id_chooser(query, ident):
-    """id chooser.  
-    
+    """id chooser.
+
     given a primary key, returns a list of shards
     to search.  here, we don't have any particular information from a
     pk so we just return all shard ids. often, youd want to do some 
     kind of round-robin strategy here so that requests are evenly 
     distributed among DBs.
-    
+
     """
     return ['north_america', 'asia', 'europe', 'south_america']
 
 def query_chooser(query):
     """query chooser.
-    
+
     this also returns a list of shard ids, which can
     just be all of them.  but here we'll search into the Query in order
     to try to narrow down the list of shards to query.
-    
+
     """
     ids = []
 
@@ -140,7 +140,7 @@ def query_chooser(query):
                 ids.append(shard_lookup[value])
             elif operator == operators.in_op:
                 ids.extend(shard_lookup[v] for v in value)
-                    
+
     if len(ids) == 0:
         return ['north_america', 'asia', 'europe', 'south_america']
     else:
@@ -148,12 +148,12 @@ def query_chooser(query):
 
 def _get_query_comparisons(query):
     """Search an orm.Query object for binary expressions.
-    
+
     Returns expressions which match a Column against one or more
     literal values as a list of tuples of the form 
     (column, operator, values).   "values" is a single value
     or tuple of values depending on the operator.
-    
+
     """
     binds = {}
     clauses = set()
@@ -216,7 +216,7 @@ create_session.configure(
                     query_chooser=query_chooser
                     )
 
-# step 6.  mapped classes.    
+# step 6.  mapped classes.
 class WeatherLocation(object):
     def __init__(self, continent, city):
         self.continent = continent
@@ -231,7 +231,7 @@ mapper(WeatherLocation, weather_locations, properties={
     'reports':relationship(Report, backref='location')
 })
 
-mapper(Report, weather_reports)    
+mapper(Report, weather_reports)
 
 
 # save and load objects!
index f2f8832cf7ca12b93f7f6f1cdb68f7aaefcf6698..72edcca53080b89f4f0e6e7d45cebaf747a4cb2c 100644 (file)
@@ -19,13 +19,13 @@ A fragment of example usage, using declarative::
 
     class SomeClass(Base):
         __tablename__ = 'sometable'
-    
+
         id = Column(Integer, primary_key=True)
         name = Column(String(50))
-    
+
         def __eq__(self, other):
             assert type(other) is SomeClass and other.id == self.id
-        
+
     sess = Session()
     sc = SomeClass(name='sc1')
     sess.add(sc)
index fa95733e29c548a5bcb0f04d4bd98bab376c826d..2983a33e21dec984fa9ee55fe3d2179af211f36c 100644 (file)
@@ -19,10 +19,10 @@ def _history_mapper(local_mapper):
     # of the info is always loaded (currently sets it on all attributes)
     for prop in local_mapper.iterate_properties:
         getattr(local_mapper.class_, prop.key).impl.active_history = True
-    
+
     super_mapper = local_mapper.inherits
     super_history_mapper = getattr(cls, '__history_mapper__', None)
-    
+
     polymorphic_on = None
     super_fks = []
     if not super_mapper or local_mapper.local_table is not super_mapper.local_table:
@@ -30,7 +30,7 @@ def _history_mapper(local_mapper):
         for column in local_mapper.local_table.c:
             if column.name == 'version':
                 continue
-                
+
             col = column.copy()
             col.unique = False
 
@@ -38,16 +38,16 @@ def _history_mapper(local_mapper):
                 super_fks.append((col.key, list(super_history_mapper.base_mapper.local_table.primary_key)[0]))
 
             cols.append(col)
-            
+
             if column is local_mapper.polymorphic_on:
                 polymorphic_on = col
-        
+
         if super_mapper:
             super_fks.append(('version', super_history_mapper.base_mapper.local_table.c.version))
             cols.append(Column('version', Integer, primary_key=True))
         else:
             cols.append(Column('version', Integer, primary_key=True))
-        
+
         if super_fks:
             cols.append(ForeignKeyConstraint(*zip(*super_fks)))
 
@@ -62,13 +62,13 @@ def _history_mapper(local_mapper):
                 col = column.copy()
                 super_history_mapper.local_table.append_column(col)
         table = None
-        
+
     if super_history_mapper:
         bases = (super_history_mapper.class_,)
     else:
         bases = local_mapper.base_mapper.class_.__bases__
     versioned_cls = type.__new__(type, "%sHistory" % cls.__name__, bases, {})
-    
+
     m = mapper(
             versioned_cls, 
             table, 
@@ -77,11 +77,11 @@ def _history_mapper(local_mapper):
             polymorphic_identity=local_mapper.polymorphic_identity
             )
     cls.__history_mapper__ = m
-    
+
     if not super_history_mapper:
         cls.version = Column('version', Integer, default=1, nullable=False)
-    
-    
+
+
 class VersionedMeta(DeclarativeMeta):
     def __init__(cls, classname, bases, dict_):
         DeclarativeMeta.__init__(cls, classname, bases, dict_)
@@ -102,21 +102,21 @@ def create_version(obj, session, deleted = False):
     obj_mapper = object_mapper(obj)
     history_mapper = obj.__history_mapper__
     history_cls = history_mapper.class_
-    
+
     obj_state = attributes.instance_state(obj)
-    
+
     attr = {}
 
     obj_changed = False
-    
+
     for om, hm in zip(obj_mapper.iterate_to_root(), history_mapper.iterate_to_root()):
         if hm.single:
             continue
-    
+
         for hist_col in hm.local_table.c:
             if hist_col.key == 'version':
                 continue
-                
+
             obj_col = om.local_table.c[hist_col.key]
 
             # get the value of the
@@ -131,7 +131,7 @@ def create_version(obj, session, deleted = False):
                 # the "unmapped" status of the subclass column on the 
                 # base class is a feature of the declarative module as of sqla 0.5.2.
                 continue
-                
+
             # expired object attributes and also deferred cols might not be in the
             # dict.  force it to load no matter what by using getattr().
             if prop.key not in obj_state.dict:
@@ -148,7 +148,7 @@ def create_version(obj, session, deleted = False):
                 # if the attribute had no value.
                 attr[hist_col.key] = a[0]
                 obj_changed = True
-    
+
     if not obj_changed:
         # not changed, but we have relationships.  OK
         # check those too
@@ -157,8 +157,8 @@ def create_version(obj, session, deleted = False):
                 attributes.get_history(obj, prop.key).has_changes():
                 obj_changed = True
                 break
-        
-    if not obj_changed and not deleted:            
+
+    if not obj_changed and not deleted:
         return
 
     attr['version'] = obj.version
@@ -167,7 +167,7 @@ def create_version(obj, session, deleted = False):
         setattr(hist, key, value)
     session.add(hist)
     obj.version += 1
-    
+
 class VersionedListener(SessionExtension):
     def before_flush(self, session, flush_context, instances):
         for obj in versioned_objects(session.dirty):
index c9cb605cd12930c1b8fe8c28dd437725cc875deb..83d769e1ef7f08cf4aed11c12f02e79aebd16306 100644 (file)
@@ -8,7 +8,7 @@ from test.lib.entities import ComparableEntity
 def setup():
     global engine
     engine = create_engine('sqlite://', echo=True)
-    
+
 class TestVersioning(TestBase):
     def setup(self):
         global Base, Session, Versioned
@@ -17,34 +17,34 @@ class TestVersioning(TestBase):
             __metaclass__ = VersionedMeta
             _decl_class_registry = Base._decl_class_registry
         Session = sessionmaker(extension=VersionedListener())
-        
+
     def teardown(self):
         clear_mappers()
         Base.metadata.drop_all()
-    
+
     def create_tables(self):
         Base.metadata.create_all()
-        
+
     def test_plain(self):
         class SomeClass(Versioned, Base, ComparableEntity):
             __tablename__ = 'sometable'
-            
+
             id = Column(Integer, primary_key=True)
             name = Column(String(50))
-        
+
         self.create_tables()
         sess = Session()
         sc = SomeClass(name='sc1')
         sess.add(sc)
         sess.commit()
-        
+
         sc.name = 'sc1modified'
         sess.commit()
-        
+
         assert sc.version == 2
-        
+
         SomeClassHistory = SomeClass.__history_mapper__.class_
-        
+
         eq_(
             sess.query(SomeClassHistory).filter(SomeClassHistory.version == 1).all(),
             [SomeClassHistory(version=1, name='sc1')]
@@ -61,7 +61,7 @@ class TestVersioning(TestBase):
         )
 
         assert sc.version == 3
-        
+
         sess.commit()
 
         sc.name = 'temp'
@@ -76,7 +76,7 @@ class TestVersioning(TestBase):
                 SomeClassHistory(version=2, name='sc1modified')
             ]
         )
-        
+
         sess.delete(sc)
         sess.commit()
 
@@ -92,41 +92,41 @@ class TestVersioning(TestBase):
     def test_from_null(self):
         class SomeClass(Versioned, Base, ComparableEntity):
             __tablename__ = 'sometable'
-            
+
             id = Column(Integer, primary_key=True)
             name = Column(String(50))
-        
+
         self.create_tables()
         sess = Session()
         sc = SomeClass()
         sess.add(sc)
         sess.commit()
-        
+
         sc.name = 'sc1'
         sess.commit()
-        
+
         assert sc.version == 2
 
     def test_deferred(self):
         """test versioning of unloaded, deferred columns."""
-        
+
         class SomeClass(Versioned, Base, ComparableEntity):
             __tablename__ = 'sometable'
 
             id = Column(Integer, primary_key=True)
             name = Column(String(50))
             data = deferred(Column(String(25)))
-            
+
         self.create_tables()
         sess = Session()
         sc = SomeClass(name='sc1', data='somedata')
         sess.add(sc)
         sess.commit()
         sess.close()
-        
+
         sc = sess.query(SomeClass).first()
         assert 'data' not in sc.__dict__
-        
+
         sc.name = 'sc1modified'
         sess.commit()
 
@@ -138,8 +138,8 @@ class TestVersioning(TestBase):
             sess.query(SomeClassHistory).filter(SomeClassHistory.version == 1).all(),
             [SomeClassHistory(version=1, name='sc1', data='somedata')]
         )
-        
-        
+
+
     def test_joined_inheritance(self):
         class BaseClass(Versioned, Base, ComparableEntity):
             __tablename__ = 'basetable'
@@ -147,9 +147,9 @@ class TestVersioning(TestBase):
             id = Column(Integer, primary_key=True)
             name = Column(String(50))
             type = Column(String(20))
-            
+
             __mapper_args__ = {'polymorphic_on':type, 'polymorphic_identity':'base'}
-            
+
         class SubClassSeparatePk(BaseClass):
             __tablename__ = 'subtable1'
 
@@ -175,7 +175,7 @@ class TestVersioning(TestBase):
         same1 = SubClassSamePk(name='same1', subdata2='same1subdata')
         sess.add_all([sep1, base1, same1])
         sess.commit()
-        
+
         base1.name = 'base1mod'
         same1.subdata2 = 'same1subdatamod'
         sep1.name ='sep1mod'
@@ -189,10 +189,10 @@ class TestVersioning(TestBase):
             [
                 SubClassSeparatePkHistory(id=1, name=u'sep1', type=u'sep', version=1), 
                 BaseClassHistory(id=2, name=u'base1', type=u'base', version=1), 
-                SubClassSamePkHistory(id=3, name=u'same1', type=u'same', version=1)            
+                SubClassSamePkHistory(id=3, name=u'same1', type=u'same', version=1)
             ]
         )
-        
+
         same1.subdata2 = 'same1subdatamod2'
 
         eq_(
@@ -201,7 +201,7 @@ class TestVersioning(TestBase):
                 SubClassSeparatePkHistory(id=1, name=u'sep1', type=u'sep', version=1), 
                 BaseClassHistory(id=2, name=u'base1', type=u'base', version=1), 
                 SubClassSamePkHistory(id=3, name=u'same1', type=u'same', version=1), 
-                SubClassSamePkHistory(id=3, name=u'same1', type=u'same', version=2)            
+                SubClassSamePkHistory(id=3, name=u'same1', type=u'same', version=2)
             ]
         )
 
@@ -213,7 +213,7 @@ class TestVersioning(TestBase):
                 BaseClassHistory(id=2, name=u'base1', type=u'base', version=1), 
                 BaseClassHistory(id=2, name=u'base1mod', type=u'base', version=2), 
                 SubClassSamePkHistory(id=3, name=u'same1', type=u'same', version=1), 
-                SubClassSamePkHistory(id=3, name=u'same1', type=u'same', version=2)            
+                SubClassSamePkHistory(id=3, name=u'same1', type=u'same', version=2)
             ]
         )
 
@@ -225,7 +225,7 @@ class TestVersioning(TestBase):
             name = Column(String(50))
             type = Column(String(50))
             __mapper_args__ = {'polymorphic_on':type, 'polymorphic_identity':'base'}
-            
+
         class SubClass(BaseClass):
 
             subname = Column(String(50))
@@ -236,21 +236,21 @@ class TestVersioning(TestBase):
 
         b1 = BaseClass(name='b1')
         sc = SubClass(name='s1', subname='sc1')
-        
+
         sess.add_all([b1, sc])
-        
+
         sess.commit()
-        
+
         b1.name='b1modified'
 
         BaseClassHistory = BaseClass.__history_mapper__.class_
         SubClassHistory = SubClass.__history_mapper__.class_
-        
+
         eq_(
             sess.query(BaseClassHistory).order_by(BaseClassHistory.id, BaseClassHistory.version).all(),
             [BaseClassHistory(id=1, name=u'b1', type=u'base', version=1)]
         )
-        
+
         sc.name ='s1modified'
         b1.name='b1modified2'
 
@@ -262,48 +262,48 @@ class TestVersioning(TestBase):
                 SubClassHistory(id=2, name=u's1', type=u'sub', version=1)
             ]
         )
-    
+
     def test_unique(self):
         class SomeClass(Versioned, Base, ComparableEntity):
             __tablename__ = 'sometable'
-            
+
             id = Column(Integer, primary_key=True)
             name = Column(String(50), unique=True)
             data = Column(String(50))
-            
+
         self.create_tables()
         sess = Session()
         sc = SomeClass(name='sc1', data='sc1')
         sess.add(sc)
         sess.commit()
-        
+
         sc.data = 'sc1modified'
         sess.commit()
-        
+
         assert sc.version == 2
-        
+
         sc.data = 'sc1modified2'
         sess.commit()
-        
+
         assert sc.version == 3
 
     def test_relationship(self):
 
         class SomeRelated(Base, ComparableEntity):
             __tablename__ = 'somerelated'
-            
+
             id = Column(Integer, primary_key=True)
 
         class SomeClass(Versioned, Base, ComparableEntity):
             __tablename__ = 'sometable'
-            
+
             id = Column(Integer, primary_key=True)
             name = Column(String(50))
             related_id = Column(Integer, ForeignKey('somerelated.id'))
             related = relationship("SomeRelated")
-            
+
         SomeClassHistory = SomeClass.__history_mapper__.class_
-            
+
         self.create_tables()
         sess = Session()
         sc = SomeClass(name='sc1')
@@ -311,13 +311,13 @@ class TestVersioning(TestBase):
         sess.commit()
 
         assert sc.version == 1
-        
+
         sr1 = SomeRelated()
         sc.related = sr1
         sess.commit()
-        
+
         assert sc.version == 2
-        
+
         eq_(
             sess.query(SomeClassHistory).filter(SomeClassHistory.version == 1).all(),
             [SomeClassHistory(version=1, name='sc1', related_id=None)]
@@ -334,4 +334,4 @@ class TestVersioning(TestBase):
         )
 
         assert sc.version == 3
-        
+
index 61ba2228bf3e43c9b11cf794260fbf480399e974..b4ce291f27fbdef7e53eb6ab9a33382733d2f38e 100644 (file)
@@ -1,7 +1,7 @@
 """
 Illustrates "vertical table" mappings.
 
-A "vertical table" refers to a technique where individual attributes of an object are stored as distinct rows in a table.   
+A "vertical table" refers to a technique where individual attributes of an object are stored as distinct rows in a table.
 The "vertical table" technique is used to persist objects which can have a varied set of attributes, at the expense of simple query control and brevity.   It is commonly found in content/document management systems in order to represent user-created structures flexibly.
 
 Two variants on the approach are given.  In the second, each row references a "datatype" which contains information about the type of information stored in the attribute, such as integer, string, or date.
index d24e845e58d628c2fe2215726b3e99497210bf7c..e33744ba1cde7320f0d5f6bfcc6f130ef30c9b9c 100644 (file)
@@ -92,7 +92,7 @@ def use_setuptools(
     try:
         import pkg_resources
     except ImportError:
-        return do_download()       
+        return do_download()
     try:
         pkg_resources.require("setuptools>="+version); return
     except pkg_resources.VersionConflict, e:
index 86fced34ff646f61eaf1d84e4679df32580c4de0..e9976cd130249c23b498c6d3c9f1e8333548007c 100644 (file)
@@ -114,7 +114,7 @@ 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.7b1'
 
 del inspect, sys
index 0c573045059b08efaf976039bf61be741e50465d..340c5b8fb066f316752c2bb1206828fa2ab13fdb 100644 (file)
@@ -7,5 +7,4 @@
 
 class Connector(object):
     pass
-    
-    
\ No newline at end of file
+
index 63c8c1d53330fec6f0be5e480dfe89f76efbeb28..f467234ca3056ca8b8bc97513f56466023999725 100644 (file)
@@ -26,13 +26,13 @@ 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
@@ -67,7 +67,7 @@ class MxODBCConnector(Connector):
             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.
@@ -97,7 +97,7 @@ class MxODBCConnector(Connector):
 
         The arg 'errorhandler' is not used by SQLAlchemy and will
         not be populated.
-        
+
         """
         opts = url.translate_connect_args(username='user')
         opts.update(url.query)
index 4f2aa390f310df6dd4ddd704ffb12578e5671c6b..c66a8a8ae3d118877015ea06f8e435e3ed75db71 100644 (file)
@@ -20,15 +20,15 @@ class PyODBCConnector(Connector):
     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')
@@ -36,7 +36,7 @@ class PyODBCConnector(Connector):
     def create_connect_args(self, url):
         opts = url.translate_connect_args(username='user')
         opts.update(url.query)
-        
+
         keys = opts
         query = url.query
 
@@ -80,7 +80,7 @@ class PyODBCConnector(Connector):
 
             connectors.extend(['%s=%s' % (k,v) for k,v in keys.iteritems()])
         return [[";".join (connectors)], connect_args]
-        
+
     def is_disconnect(self, e):
         if isinstance(e, self.dbapi.ProgrammingError):
             return "The cursor's connection has been closed." in str(e) or \
@@ -93,7 +93,7 @@ class PyODBCConnector(Connector):
     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
@@ -108,7 +108,7 @@ class PyODBCConnector(Connector):
         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)
 
index 941dd17aee0468fdb9559172cc027acde2a0a07a..a9ff5ec95c567f763732dfc36a0054588a6a3673 100644 (file)
@@ -9,18 +9,18 @@ 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
@@ -29,14 +29,14 @@ class ZxJDBCConnector(Connector):
     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)
index dfeaf23c2ea6ae9b2ef7f91e5ed1cbd245863c22..0dd09cebf3d316248a45fbb535b9dec7b5f1a09a 100644 (file)
@@ -153,7 +153,7 @@ class AccessDialect(default.DefaultDialect):
     supports_sane_multi_rowcount = False
 
     ported_sqla_06 = False
-    
+
     def type_descriptor(self, typeobj):
         newobj = types.adapt_type(typeobj, self.colspecs)
         return newobj
@@ -341,7 +341,7 @@ class AccessCompiler(compiler.SQLCompiler):
             '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 ""
index 1fdedbafa589e7f0774f6040d4a1bfde7777c358..e87b5bb5c6fbec00d43d51ee8ada37f2da2ed1b3 100644 (file)
@@ -12,11 +12,11 @@ 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'
 )
-    
-    
+
+
index d6939777bcb71e3efd55a135dca7b4dc436878f5..de880171fb965887c7803cc6736db208046c65b2 100644 (file)
@@ -194,7 +194,7 @@ class FBTypeCompiler(compiler.GenericTypeCompiler):
     def visit_VARCHAR(self, type_):
         basic = super(FBTypeCompiler, self).visit_VARCHAR(type_)
         return self._extend_string(type_, basic)
-        
+
 
 
 class FBCompiler(sql.compiler.SQLCompiler):
index a2624534c02dd7cdd9a75e76cd1a28dba447e056..ad8d44262f4c1fecb06762e55932a6466636d203 100644 (file)
@@ -13,7 +13,7 @@ The connection URL is of the form
 
 Kinterbasedb backend specific keyword arguments are:
 
-* type_conv - select the kind of mapping done on the types: by default  
+* type_conv - select the kind of mapping done on the types: by default
   SQLAlchemy uses 200 with Unicode, datetime and decimal support (see
   details__).
 
@@ -34,11 +34,11 @@ Kinterbasedb backend specific keyword arguments are:
   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
@@ -66,23 +66,23 @@ class FBExecutionContext_kinterbasdb(FBExecutionContext):
             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)
@@ -91,7 +91,7 @@ class FBDialect_kinterbasdb(FBDialect):
         self.concurrency_level = concurrency_level
         if enable_rowcount:
             self.supports_sane_rowcount = True
-        
+
     @classmethod
     def dbapi(cls):
         k = __import__('kinterbasdb')
@@ -103,13 +103,13 @@ class FBDialect_kinterbasdb(FBDialect):
             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:
index a97b445a3e60fd58306ec21068ed5fad258fa30d..1ea8d4e3919613fb88e644a3ff9f0c84aa19521d 100644 (file)
@@ -218,7 +218,7 @@ 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
@@ -232,13 +232,13 @@ class InformixDialect(default.DefaultDialect):
 
     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')
@@ -327,7 +327,7 @@ class InformixDialect(default.DefaultDialect):
                     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)
index 150a69d7f624326ef0105156f6a1687859fe3933..c8198381693a4563f494c725c8b30d0232b6af45 100644 (file)
@@ -10,7 +10,7 @@ Support for the informixdb DBAPI.
 informixdb is available at:
 
     http://informixdb.sourceforge.net/
-    
+
 Connecting
 ^^^^^^^^^^
 
index 4ca81b24cc5961c8042ac575d41b36ce21b8eaa3..abc7ff10b06f68b05a34755474d808003292fb38 100644 (file)
@@ -323,7 +323,7 @@ class MaxDBTypeCompiler(compiler.GenericTypeCompiler):
 
     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)
@@ -331,10 +331,10 @@ class MaxDBTypeCompiler(compiler.GenericTypeCompiler):
             return 'FIXED(%s)' % type_.precision
         else:
             return 'INTEGER'
-    
+
     def visit_BOOLEAN(self, type_):
         return "BOOLEAN"
-        
+
 colspecs = {
     sqltypes.Numeric: MaxNumeric,
     sqltypes.DateTime: MaxTimestamp,
@@ -480,7 +480,7 @@ class MaxDBCompiler(compiler.SQLCompiler):
     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'
 
@@ -768,7 +768,7 @@ class MaxDBDDLCompiler(compiler.DDLCompiler):
           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))):
@@ -825,7 +825,7 @@ class MaxDBDialect(default.DefaultDialect):
 
     colspecs = colspecs
     ischema_names = ischema_names
-    
+
     # MaxDB-specific
     datetimeformat = 'internal'
 
index 4fd9dd418a759226612f2e22c3f1b8b10b76cf08..da04d809f24c75faba15d74d6cd7ea8d2e8aa660 100644 (file)
@@ -8,7 +8,7 @@ from sqlalchemy.dialects.maxdb.base import MaxDBDialect
 
 class MaxDBDialect_sapdb(MaxDBDialect):
     driver = 'sapdb'
-    
+
     @classmethod
     def dbapi(cls):
         from sapdb import dbapi as _dbapi
index d18880931be49a3cb19221f852103c4b4758721d..355214d89258fb3ec5c20a21d8dbf38a6d871bf8 100644 (file)
@@ -31,7 +31,7 @@ class MSDialect_adodbapi(MSDialect):
     supports_unicode = sys.maxunicode == 65535
     supports_unicode_statements = True
     driver = 'adodbapi'
-    
+
     @classmethod
     def import_dbapi(cls):
         import adodbapi as module
index dda63080da57618f672297b10aaf8e98041a61a8..290cd1019bd7604286fa63cf4d6f38b0426021d9 100644 (file)
@@ -18,7 +18,7 @@ Auto Increment Behavior
 ``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),
@@ -261,7 +261,7 @@ class SMALLDATETIME(_DateTimeBase, sqltypes.DateTime):
 
 class DATETIME2(_DateTimeBase, sqltypes.DateTime):
     __visit_name__ = 'DATETIME2'
-    
+
     def __init__(self, precision=None, **kw):
         super(DATETIME2, self).__init__(**kw)
         self.precision = precision
@@ -270,7 +270,7 @@ class DATETIME2(_DateTimeBase, sqltypes.DateTime):
 # TODO: is this not an Interval ?
 class DATETIMEOFFSET(sqltypes.TypeEngine):
     __visit_name__ = 'DATETIMEOFFSET'
-    
+
     def __init__(self, precision=None, **kwargs):
         self.precision = precision
 
@@ -298,7 +298,7 @@ class NTEXT(_StringType, sqltypes.UnicodeText):
     characters."""
 
     __visit_name__ = 'NTEXT'
-    
+
     def __init__(self, length=None, collation=None, **kw):
         """Construct a NTEXT.
 
@@ -405,7 +405,7 @@ class IMAGE(sqltypes.LargeBinary):
 
 class BIT(sqltypes.TypeEngine):
     __visit_name__ = 'BIT'
-    
+
 
 class MONEY(sqltypes.TypeEngine):
     __visit_name__ = 'MONEY'
@@ -487,13 +487,13 @@ class MSTypeCompiler(compiler.GenericTypeCompiler):
             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])
 
@@ -535,10 +535,10 @@ class MSTypeCompiler(compiler.GenericTypeCompiler):
 
     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_)
 
@@ -570,7 +570,7 @@ class MSTypeCompiler(compiler.GenericTypeCompiler):
             return self.visit_DATETIME(type_)
         else:
             return self.visit_TIME(type_)
-            
+
     def visit_large_binary(self, type_):
         return self.visit_IMAGE(type_)
 
@@ -600,7 +600,7 @@ class MSExecutionContext(default.DefaultExecutionContext):
     _select_lastrowid = False
     _result_proxy = None
     _lastrowid = None
-    
+
     def pre_exec(self):
         """Activate IDENTITY_INSERT if needed."""
 
@@ -608,25 +608,25 @@ class MSExecutionContext(default.DefaultExecutionContext):
             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(
@@ -640,17 +640,17 @@ class MSExecutionContext(default.DefaultExecutionContext):
         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" %  
+                        "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:
@@ -670,7 +670,7 @@ class MSExecutionContext(default.DefaultExecutionContext):
 
 class MSSQLCompiler(compiler.SQLCompiler):
     returning_precedes_values = True
-    
+
     extract_map = util.update_copy(
         compiler.SQLCompiler.extract_map,
         {
@@ -686,31 +686,31 @@ class MSSQLCompiler(compiler.SQLCompiler):
 
     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.
@@ -743,7 +743,7 @@ class MSSQLCompiler(compiler.SQLCompiler):
                 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'])
@@ -853,7 +853,7 @@ class MSSQLCompiler(compiler.SQLCompiler):
             target = stmt.table.alias("inserted")
         else:
             target = stmt.table.alias("deleted")
-        
+
         adapter = sql_util.ClauseAdapter(target)
         def col_label(col):
             adapted = adapter.traverse(col)
@@ -861,7 +861,7 @@ class MSSQLCompiler(compiler.SQLCompiler):
                 return adapted.label(c.key)
             else:
                 return self.label_select_column(None, adapted, asfrom=False)
-            
+
         columns = [
             self.process(
                 col_label(c), 
@@ -896,10 +896,10 @@ class MSSQLCompiler(compiler.SQLCompiler):
 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
 
@@ -927,9 +927,9 @@ class MSSQLStrictCompiler(MSSQLCompiler):
         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
@@ -950,12 +950,12 @@ class MSDDLCompiler(compiler.DDLCompiler):
                 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
@@ -1015,13 +1015,13 @@ class MSDialect(default.DefaultDialect):
     }
 
     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
@@ -1039,7 +1039,7 @@ class MSDialect(default.DefaultDialect):
         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.")
@@ -1048,7 +1048,7 @@ class MSDialect(default.DefaultDialect):
 
     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):
@@ -1064,7 +1064,7 @@ class MSDialect(default.DefaultDialect):
         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:
@@ -1138,7 +1138,7 @@ class MSDialect(default.DefaultDialect):
         # 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)
 
@@ -1186,7 +1186,7 @@ class MSDialect(default.DefaultDialect):
         for row in rp:
             if row['index_id'] in indexes:
                 indexes[row['index_id']]['column_names'].append(row['name'])
-        
+
         return indexes.values()
 
     @reflection.cache
@@ -1315,7 +1315,7 @@ class MSDialect(default.DefaultDialect):
         # the constrained column
         C  = ischema.key_constraints.alias('C') 
         # information_schema.constraint_column_usage: 
-        # the referenced column                                                
+        # the referenced column
         R  = ischema.key_constraints.alias('R') 
 
         # Primary key constraints
@@ -1337,7 +1337,7 @@ class MSDialect(default.DefaultDialect):
         #information_schema.referential_constraints
         RR = ischema.ref_constraints
         # information_schema.table_constraints
-        TC = ischema.constraints        
+        TC = ischema.constraints
         # information_schema.constraint_column_usage: 
         # the constrained column
         C  = ischema.key_constraints.alias('C') 
@@ -1361,12 +1361,12 @@ class MSDialect(default.DefaultDialect):
                        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,
@@ -1377,7 +1377,7 @@ class MSDialect(default.DefaultDialect):
             }
 
         fkeys = util.defaultdict(fkey_rec)
-        
+
         for r in connection.execute(s).fetchall():
             scol, rschema, rtbl, rcol, rfknm, fkmatch, fkuprule, fkdelrule = r
 
@@ -1388,11 +1388,11 @@ class MSDialect(default.DefaultDialect):
 
                 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)
 
index 5806ebfa8aa1499da2cd600d642986274489d232..87dd0a1673e5f0c7c45e947d68207c68a959e29b 100644 (file)
@@ -13,12 +13,12 @@ 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"),
@@ -74,8 +74,8 @@ ref_constraints = Table("REFERENTIAL_CONSTRAINTS", ischema,
     Column("CONSTRAINT_NAME", CoerceUnicode, key="constraint_name"),
     # TODO: is CATLOG misspelled ?
     Column("UNIQUE_CONSTRAINT_CATLOG", CoerceUnicode,
-                                        key="unique_constraint_catalog"),  
-                                        
+                                        key="unique_constraint_catalog"),
+
     Column("UNIQUE_CONSTRAINT_SCHEMA", CoerceUnicode,
                                         key="unique_constraint_schema"),
     Column("UNIQUE_CONSTRAINT_NAME", CoerceUnicode,
index ba695ef08aac80368de1c22f591ca7ba5cadafb8..6a830509a7ebea90b1f74f4b84fbd0d69f3f77a7 100644 (file)
@@ -20,7 +20,7 @@ Connecting
 Connection is via DSN::
 
     mssql+mxodbc://<username>:<password>@<dsnname>
-    
+
 Execution Modes
 ~~~~~~~~~~~~~~~
 
@@ -72,7 +72,7 @@ class MSExecutionContext_mxodbc(MSExecutionContext_pyodbc):
     #       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
index aa3bf45d2c18ce2c5c7959962e96602918e57434..192e6336697730a2a16ba53a3f5beed44e191ab1 100644 (file)
@@ -12,10 +12,10 @@ 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>
@@ -53,7 +53,7 @@ class MSDialect_pymssql(MSDialect):
     supports_sane_rowcount = False
     max_identifier_length = 30
     driver = 'pymssql'
-    
+
     colspecs = util.update_copy(
         MSDialect.colspecs,
         {
@@ -67,7 +67,7 @@ class MSDialect_pymssql(MSDialect):
         # 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 "
index 90a43889e90546357e79debde220dab1a5a1eb40..9b88dce2ab3b618dbe63f1020c7a18e946b91ac1 100644 (file)
@@ -86,15 +86,15 @@ 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)
 
@@ -104,7 +104,7 @@ class _MSNumeric_pyodbc(sqltypes.Numeric):
         def process(value):
             if self.asdecimal and \
                     isinstance(value, decimal.Decimal):
-                
+
                 adjusted = value.adjusted()
                 if adjusted < 0:
                     return self._small_dec_to_string(value)
@@ -116,10 +116,10 @@ class _MSNumeric_pyodbc(sqltypes.Numeric):
             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 ''),
@@ -147,24 +147,24 @@ class _MSNumeric_pyodbc(sqltypes.Numeric):
                 "".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 
@@ -173,7 +173,7 @@ class MSExecutionContext_pyodbc(MSExecutionContext):
                 self.dialect.use_scope_identity and \
                 len(self.parameters[0]):
             self._embedded_scope_identity = True
-            
+
             self.statement += "; select scope_identity()"
 
     def post_exec(self):
@@ -185,13 +185,13 @@ class MSExecutionContext_pyodbc(MSExecutionContext):
                 try:
                     # fetchall() ensures the cursor is consumed 
                     # without closing it (FreeTDS particularly)
-                    row = self.cursor.fetchall()[0]  
+                    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()
@@ -202,14 +202,14 @@ 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
@@ -217,5 +217,5 @@ class MSDialect_pyodbc(PyODBCConnector, MSDialect):
                         hasattr(self.dbapi.Cursor, 'nextset')
         self._need_decimal_fix = self.dbapi and \
                                 tuple(self.dbapi.version.split(".")) < (2, 1, 8)
-        
+
 dialect = MSDialect_pyodbc
index 6eb54588a33b2472341e85c4bc6b82479dadc429..fe1ef49b26f161c7157306f2df4bdd13321d5992 100644 (file)
@@ -18,7 +18,7 @@ from sqlalchemy.dialects.mysql.base import \
     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',
index 6585c40168660adb359f3ae46ed3d4a8b9d37a6d..e26d83f0aa7d9d3e6b37005d29423dcaf6bf8cc8 100644 (file)
@@ -39,7 +39,7 @@ Connecting
 ----------
 
 See the API documentation on individual drivers for details on connecting.
-    
+
 Connection Timeouts
 -------------------
 
@@ -235,7 +235,7 @@ class _NumericType(object):
         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 \
@@ -274,7 +274,7 @@ class _StringType(sqltypes.String):
         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:])
@@ -291,9 +291,9 @@ class _StringType(sqltypes.String):
 
 class NUMERIC(_NumericType, sqltypes.NUMERIC):
     """MySQL NUMERIC type."""
-    
+
     __visit_name__ = 'NUMERIC'
-    
+
     def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
         """Construct a NUMERIC.
 
@@ -315,9 +315,9 @@ class NUMERIC(_NumericType, sqltypes.NUMERIC):
 
 class DECIMAL(_NumericType, sqltypes.DECIMAL):
     """MySQL DECIMAL type."""
-    
+
     __visit_name__ = 'DECIMAL'
-    
+
     def __init__(self, precision=None, scale=None, asdecimal=True, **kw):
         """Construct a DECIMAL.
 
@@ -337,7 +337,7 @@ class DECIMAL(_NumericType, sqltypes.DECIMAL):
         super(DECIMAL, self).__init__(precision=precision, scale=scale,
                                       asdecimal=asdecimal, **kw)
 
-    
+
 class DOUBLE(_FloatType):
     """MySQL DOUBLE type."""
 
@@ -538,12 +538,12 @@ class BIT(sqltypes.TypeEngine):
 
     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
@@ -710,7 +710,7 @@ class LONGTEXT(_StringType):
         """
         super(LONGTEXT, self).__init__(**kwargs)
 
-    
+
 class VARCHAR(_StringType, sqltypes.VARCHAR):
     """MySQL VARCHAR type, for variable-length character data."""
 
@@ -818,7 +818,7 @@ class NCHAR(_StringType, sqltypes.NCHAR):
 
 class TINYBLOB(sqltypes._Binary):
     """MySQL TINYBLOB type, for binary data up to 2^8 bytes."""
-    
+
     __visit_name__ = 'TINYBLOB'
 
 class MEDIUMBLOB(sqltypes._Binary):
@@ -886,7 +886,7 @@ class ENUM(sqltypes.Enum, _StringType):
 
         """
         self.quoting = kw.pop('quoting', 'auto')
-        
+
         if self.quoting == 'auto' and len(enums):
             # What quoting character are we using?
             q = None
@@ -919,7 +919,7 @@ class ENUM(sqltypes.Enum, _StringType):
         kw.pop('native_enum', None)
         _StringType.__init__(self, length=length, **kw)
         sqltypes.Enum.__init__(self, *enums)
-    
+
     @classmethod
     def _strip_enums(cls, enums):
         strip_enums = []
@@ -929,7 +929,7 @@ class ENUM(sqltypes.Enum, _StringType):
                 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):
@@ -941,7 +941,7 @@ class ENUM(sqltypes.Enum, _StringType):
             else:
                 return value
         return process
-    
+
     def adapt(self, impltype, **kw):
         kw['strict'] = self.strict
         return sqltypes.Enum.adapt(self, impltype, **kw)
@@ -1121,19 +1121,19 @@ class MySQLCompiler(compiler.SQLCompiler):
     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))
 
@@ -1170,7 +1170,7 @@ class MySQLCompiler(compiler.SQLCompiler):
         # 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)
@@ -1182,7 +1182,7 @@ class MySQLCompiler(compiler.SQLCompiler):
         if self.dialect._backslash_escapes:
             value = value.replace('\\', '\\\\')
         return value
-        
+
     def get_select_precolumns(self, select):
         if isinstance(select._distinct, basestring):
             return select._distinct.upper() + " "
@@ -1274,7 +1274,7 @@ class MySQLDDLCompiler(compiler.DDLCompiler):
     def create_table_constraints(self, table):
         """Get table constraints."""
         constraint_string = super(MySQLDDLCompiler, self).create_table_constraints(table)
-        
+
         is_innodb = table.kwargs.has_key('mysql_engine') and \
                     table.kwargs['mysql_engine'].lower() == 'innodb'
 
@@ -1287,7 +1287,7 @@ class MySQLDDLCompiler(compiler.DDLCompiler):
                 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
 
 
@@ -1301,7 +1301,7 @@ class MySQLDDLCompiler(compiler.DDLCompiler):
         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')
@@ -1349,7 +1349,7 @@ class MySQLDDLCompiler(compiler.DDLCompiler):
 
     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))
@@ -1390,10 +1390,10 @@ class MySQLTypeCompiler(compiler.GenericTypeCompiler):
         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'):
@@ -1416,10 +1416,10 @@ class MySQLTypeCompiler(compiler.GenericTypeCompiler):
                              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")
@@ -1451,7 +1451,7 @@ class MySQLTypeCompiler(compiler.GenericTypeCompiler):
                                  '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))
@@ -1459,19 +1459,19 @@ class MySQLTypeCompiler(compiler.GenericTypeCompiler):
             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})
@@ -1495,7 +1495,7 @@ class MySQLTypeCompiler(compiler.GenericTypeCompiler):
             return "BIT(%s)" % type_.length
         else:
             return "BIT"
-    
+
     def visit_DATETIME(self, type_):
         return "DATETIME"
 
@@ -1513,34 +1513,34 @@ class MySQLTypeCompiler(compiler.GenericTypeCompiler):
             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 when rendered on MySQL")
-    
+
     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".
@@ -1548,32 +1548,32 @@ class MySQLTypeCompiler(compiler.GenericTypeCompiler):
             return self._extend_string(type_, {'national':True}, "VARCHAR(%(length)s)" % {'length': type_.length})
         else:
             raise exc.InvalidRequestError("NVARCHAR requires a length when rendered on MySQL")
-    
+
     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"
 
@@ -1588,13 +1588,13 @@ class MySQLTypeCompiler(compiler.GenericTypeCompiler):
         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):
 
@@ -1604,7 +1604,7 @@ class MySQLIdentifierPreparer(compiler.IdentifierPreparer):
         if not server_ansiquotes:
             quote = "`"
         else:
-            quote = '"'    
+            quote = '"'
 
         super(MySQLIdentifierPreparer, self).__init__(
                                                 dialect, 
@@ -1618,34 +1618,34 @@ class MySQLIdentifierPreparer(compiler.IdentifierPreparer):
 
 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)
 
@@ -1705,7 +1705,7 @@ class MySQLDialect(default.DefaultDialect):
         if isinstance(e, self.dbapi.OperationalError):
             return self._extract_error_code(e) in \
                         (2006, 2013, 2014, 2045, 2055)
-        elif isinstance(e, self.dbapi.InterfaceError):  
+        elif isinstance(e, self.dbapi.InterfaceError):
             # if underlying connection is closed, 
             # this is the error you get
             return "(0, '')" in str(e)
@@ -1729,7 +1729,7 @@ class MySQLDialect(default.DefaultDialect):
 
     def _extract_error_code(self, exception):
         raise NotImplementedError()
-    
+
     def _get_default_schema_name(self, connection):
         return connection.execute('SELECT DATABASE()').scalar()
 
@@ -1764,7 +1764,7 @@ class MySQLDialect(default.DefaultDialect):
         finally:
             if rs:
                 rs.close()
-    
+
     def initialize(self, connection):
         default.DefaultDialect.initialize(self, connection)
         self._connection_charset = self._detect_charset(connection)
@@ -1781,7 +1781,7 @@ class MySQLDialect(default.DefaultDialect):
     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")
@@ -1806,7 +1806,7 @@ class MySQLDialect(default.DefaultDialect):
 
             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
@@ -1848,7 +1848,7 @@ class MySQLDialect(default.DefaultDialect):
 
         parsed_state = self._parsed_state_or_create(connection, table_name, schema, **kw)
         default_schema = None
-        
+
         fkeys = []
 
         for spec in parsed_state.constraints:
@@ -1886,7 +1886,7 @@ class MySQLDialect(default.DefaultDialect):
     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
@@ -1926,14 +1926,14 @@ class MySQLDialect(default.DefaultDialect):
                         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
@@ -1941,7 +1941,7 @@ class MySQLDialect(default.DefaultDialect):
         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
@@ -1956,7 +1956,7 @@ class MySQLDialect(default.DefaultDialect):
                                            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."""
 
@@ -2030,10 +2030,10 @@ class MySQLDialect(default.DefaultDialect):
                 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``."""
@@ -2082,17 +2082,17 @@ class MySQLDialect(default.DefaultDialect):
 
 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
@@ -2125,9 +2125,9 @@ class MySQLTableDefinitionParser(object):
                     state.constraints.append(spec)
                 else:
                     pass
-                    
+
         return state
-        
+
     def _parse_constraints(self, line):
         """Parse a KEY or CONSTRAINT line.
 
@@ -2278,7 +2278,7 @@ class MySQLTableDefinitionParser(object):
         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)
index ced8730394308ed7e14454ab5d17e9042d110b9c..e9e1cdbba47a9f147c90501ed2004c6938794130 100644 (file)
@@ -9,7 +9,7 @@
 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
@@ -18,7 +18,7 @@ Connecting
 Connect string format::
 
     mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
-    
+
 Character Sets
 --------------
 
@@ -42,7 +42,7 @@ Known Issues
 -------------
 
 MySQL-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``.   
+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)
@@ -60,25 +60,25 @@ from sqlalchemy import exc, log, schema, sql, types as sqltypes, util
 from sqlalchemy import processors
 
 class MySQLExecutionContext_mysqldb(MySQLExecutionContext):
-    
+
     @property
     def rowcount(self):
         if hasattr(self, '_rowcount'):
             return self._rowcount
         else:
             return self.cursor.rowcount
-        
-        
+
+
 class MySQLCompiler_mysqldb(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_mysqldb(MySQLIdentifierPreparer):
-    
+
     def _escape_identifier(self, value):
         value = value.replace(self.escape_quote, self.escape_to_quote)
         return value.replace("%", "%%")
@@ -95,13 +95,13 @@ class MySQLDialect_mysqldb(MySQLDialect):
     execution_ctx_cls = MySQLExecutionContext_mysqldb
     statement_compiler = MySQLCompiler_mysqldb
     preparer = MySQLIdentifierPreparer_mysqldb
-    
+
     colspecs = util.update_copy(
         MySQLDialect.colspecs,
         {
         }
     )
-    
+
     @classmethod
     def dbapi(cls):
         return __import__('MySQLdb')
@@ -149,7 +149,7 @@ class MySQLDialect_mysqldb(MySQLDialect):
                 pass
             opts['client_flag'] = client_flag
         return [[], opts]
-    
+
     def _get_server_version_info(self, connection):
         dbapi_con = connection.connection
         version = []
index b4d9485d364ff25d56ab1ac188e03a7c30854989..d3ef839b14da189f8a542af637bf5fa11cc8b5ef 100644 (file)
@@ -9,7 +9,7 @@
 OurSQL is available at:
 
     http://packages.python.org/oursql/
-    
+
 Connecting
 -----------
 
@@ -61,7 +61,7 @@ class MySQLExecutionContext_oursql(MySQLExecutionContext):
     @property
     def plain_query(self):
         return self.execution_options.get('_oursql_plain_query', False)
-    
+
 class MySQLDialect_oursql(MySQLDialect):
     driver = 'oursql'
 # Py3K
@@ -70,9 +70,9 @@ class MySQLDialect_oursql(MySQLDialect):
     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
@@ -132,7 +132,7 @@ class MySQLDialect_oursql(MySQLDialect):
         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):
@@ -140,7 +140,7 @@ class MySQLDialect_oursql(MySQLDialect):
                                         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().\
@@ -159,7 +159,7 @@ class MySQLDialect_oursql(MySQLDialect):
                                         schema=schema,
                                         **kw
         )
-        
+
     def get_view_names(self, connection, schema=None, **kw):
         return MySQLDialect.get_view_names(self,
                                             connection.connect().\
@@ -167,27 +167,27 @@ class MySQLDialect_oursql(MySQLDialect):
                                             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,
@@ -196,7 +196,7 @@ class MySQLDialect_oursql(MySQLDialect):
                                 table, charset, full_name)
 
     def is_disconnect(self, e):
-        if isinstance(e, self.dbapi.ProgrammingError):  
+        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)
@@ -240,7 +240,7 @@ class MySQLDialect_oursql(MySQLDialect):
 
     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):
index d103c56c8519f3fcc86a0c3dea8543ad65c187f2..84d43cf272db2f2ce4a184cd641193685646a0d6 100644 (file)
@@ -47,7 +47,7 @@ class MySQLDialect_pyodbc(PyODBCConnector, MySQLDialect):
     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)
@@ -70,7 +70,7 @@ class MySQLDialect_pyodbc(PyODBCConnector, MySQLDialect):
 
         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)
index defab294746a560ff23df9f706a0be81ebfe4cc1..bacad37041e51f713421f2cab7ca074c7867868b 100644 (file)
@@ -132,7 +132,7 @@ from sqlalchemy.sql import operators as sql_operators, functions as sql_function
 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 '
@@ -155,33 +155,33 @@ 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):
@@ -192,44 +192,44 @@ class LONG(sqltypes.Text):
 
 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
@@ -264,19 +264,19 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler):
     # 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 
@@ -295,24 +295,24 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler):
 
     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}
@@ -321,7 +321,7 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler):
 
     def visit_NVARCHAR(self, type_):
         return "NVARCHAR2(%(length)s)" % {'length' : type_.length}
-    
+
     def visit_text(self, type_):
         return self.visit_CLOB(type_)
 
@@ -336,29 +336,29 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler):
 
     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):
         super(OracleCompiler, self).__init__(*args, **kwargs)
         self.__wheres = {}
@@ -366,27 +366,27 @@ class OracleCompiler(compiler.SQLCompiler):
 
     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:
             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.
 
@@ -418,15 +418,15 @@ class OracleCompiler(compiler.SQLCompiler):
                                 {'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:
@@ -440,11 +440,11 @@ class OracleCompiler(compiler.SQLCompiler):
 
     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:
@@ -454,19 +454,19 @@ class OracleCompiler(compiler.SQLCompiler):
             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):
@@ -484,7 +484,7 @@ class OracleCompiler(compiler.SQLCompiler):
                     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:
@@ -513,7 +513,7 @@ class OracleCompiler(compiler.SQLCompiler):
 
                 limitselect._oracle_visit = True
                 limitselect._is_wrapper = True
-                
+
                 # If needed, add the limiting clause
                 if select._limit is not None:
                     max_row = select._limit
@@ -563,7 +563,7 @@ class OracleDDLCompiler(compiler.DDLCompiler):
         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:
@@ -571,11 +571,11 @@ class OracleDDLCompiler(compiler.DDLCompiler):
                 "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(["_", "$"])
 
@@ -586,18 +586,18 @@ class OracleIdentifierPreparer(compiler.IdentifierPreparer):
                 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):
         return int(self._execute_scalar("SELECT " + 
                     self.dialect.identifier_preparer.format_sequence(seq) + 
                     ".nextval FROM DUAL"))
-    
+
 class OracleDialect(default.DefaultDialect):
     name = 'oracle'
     supports_alter = True
@@ -610,21 +610,21 @@ class OracleDialect(default.DefaultDialect):
     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, 
@@ -641,7 +641,7 @@ class OracleDialect(default.DefaultDialect):
                                     'implicit_returning',
                                     self.server_version_info > (10, )
                                     )
-        
+
         if self._is_oracle_8:
             self.colspecs = self.colspecs.copy()
             self.colspecs.pop(sqltypes.Interval)
@@ -651,7 +651,7 @@ class OracleDialect(default.DefaultDialect):
     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
@@ -659,7 +659,7 @@ class OracleDialect(default.DefaultDialect):
     @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
@@ -868,7 +868,7 @@ class OracleDialect(default.DefaultDialect):
     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,
@@ -883,7 +883,7 @@ class OracleDialect(default.DefaultDialect):
             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})
@@ -896,7 +896,7 @@ class OracleDialect(default.DefaultDialect):
                                       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):
@@ -983,7 +983,7 @@ class OracleDialect(default.DefaultDialect):
         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) = \
@@ -1038,7 +1038,7 @@ class OracleDialect(default.DefaultDialect):
             }
 
         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]])
@@ -1067,12 +1067,12 @@ class OracleDialect(default.DefaultDialect):
                         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)
 
@@ -1102,7 +1102,7 @@ class OracleDialect(default.DefaultDialect):
 
 class _OuterJoinColumn(sql.ClauseElement):
     __visit_name__ = 'outer_join_column'
-    
+
     def __init__(self, column):
         self.column = column
 
index f4f4912eff43ecccf5fac82551f18c0b745d73c4..04f3aab9548cc459ece4e13d6abcf74cb80c27c6 100644 (file)
@@ -31,7 +31,7 @@ URL, or as keyword arguments to :func:`~sqlalchemy.create_engine()` are:
 
 * *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.
@@ -62,7 +62,7 @@ these to strings so that the interface of the Binary type is consistent with tha
 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.  
+cursor is broken.
 
 To disable this processing, pass ``auto_convert_lobs=False`` to :func:`create_engine()`.
 
@@ -144,7 +144,7 @@ class _OracleNumeric(sqltypes.Numeric):
         # 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:
@@ -190,7 +190,7 @@ class _LOBMixin(object):
         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()
@@ -213,11 +213,11 @@ class _NativeUnicodeMixin(object):
         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
@@ -225,7 +225,7 @@ class _OracleChar(_NativeUnicodeMixin, sqltypes.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
@@ -258,7 +258,7 @@ class _OracleInteger(sqltypes.Integer):
                 val = int(val)
             return val
         return to_int
-        
+
 class _OracleBinary(_LOBMixin, sqltypes.LargeBinary):
     def get_dbapi_type(self, dbapi):
         return dbapi.BLOB
@@ -269,14 +269,14 @@ class _OracleBinary(_LOBMixin, sqltypes.LargeBinary):
 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):
@@ -286,9 +286,9 @@ class OracleCompiler_cx_oracle(OracleCompiler):
         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)
@@ -331,7 +331,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext):
                     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:
@@ -353,15 +353,15 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext):
                 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
@@ -385,16 +385,16 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext):
 
 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().  
+    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)
@@ -403,17 +403,17 @@ class OracleExecutionContext_cx_oracle_with_unicode(OracleExecutionContext_cx_or
     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'):
@@ -421,7 +421,7 @@ class ReturningResultProxy(base.FullyBufferedResultProxy):
             else:
                 ret.append((c.anon_label, c.type))
         return ret
-    
+
     def _buffer_rows(self):
         return [tuple(self._returning_params["ret_%d" % i] 
                     for i, c in enumerate(self._returning_params))]
@@ -431,7 +431,7 @@ class OracleDialect_cx_oracle(OracleDialect):
     statement_compiler = OracleCompiler_cx_oracle
 
     driver = "cx_oracle"
-    
+
     colspecs = colspecs = {
         sqltypes.Numeric: _OracleNumeric,
         sqltypes.Date : _OracleDate, # generic type, assume datetime.date is desired
@@ -452,9 +452,9 @@ class OracleDialect_cx_oracle(OracleDialect):
         oracle.ROWID: _OracleRowid,
     }
 
-    
+
     execute_sequence_format = list
-    
+
     def __init__(self, 
                 auto_setinputsizes=True, 
                 auto_convert_lobs=True, 
@@ -468,12 +468,12 @@ class OracleDialect_cx_oracle(OracleDialect):
         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:  
+        else:
             self.cx_oracle_ver = (0, 0, 0)
-        
+
         def types(*names):
             return set([
                         getattr(self.dbapi, name, None) for name in names
@@ -536,28 +536,28 @@ class OracleDialect_cx_oracle(OracleDialect):
         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(
@@ -576,20 +576,20 @@ class OracleDialect_cx_oracle(OracleDialect):
                 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):
@@ -616,12 +616,12 @@ class OracleDialect_cx_oracle(OracleDialect):
             # 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',
index fdf818a99460ad7f8640215abd1ecc843a68c635..48d1a8c3bcf003d8cee85706835e58b31a64dfad 100644 (file)
@@ -11,6 +11,6 @@ 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
index 009f8fd94255c61f848940be395f59c997de986d..31f699d2bb973946e74480dff969d15194dafe47 100644 (file)
@@ -4,7 +4,7 @@
 # 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.  
+"""Support for the PostgreSQL database.
 
 For information on connecting using specific drivers, see the documentation
 section regarding that driver.
@@ -64,7 +64,7 @@ use the :meth:`._UpdateBase.returning` method on a per-statement basis::
     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')
@@ -113,7 +113,7 @@ class BYTEA(sqltypes.LargeBinary):
 
 class DOUBLE_PRECISION(sqltypes.Float):
     __visit_name__ = 'DOUBLE_PRECISION'
-    
+
 class INET(sqltypes.TypeEngine):
     __visit_name__ = "INET"
 PGInet = INET
@@ -131,7 +131,7 @@ class TIMESTAMP(sqltypes.TIMESTAMP):
         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)
@@ -139,15 +139,15 @@ class TIME(sqltypes.TIME):
 
 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)
@@ -155,44 +155,44 @@ class INTERVAL(sqltypes.TypeEngine):
     @property
     def _type_affinity(self):
         return sqltypes.Interval
-        
+
 PGInterval = INTERVAL
 
 class BIT(sqltypes.TypeEngine):
     __visit_name__ = 'BIT'
     def __init__(self, length=1):
         self.length= length
-        
+
 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):
@@ -202,7 +202,7 @@ class UUID(sqltypes.TypeEngine):
             return process
         else:
             return None
-            
+
     def result_processor(self, dialect, coltype):
         if self.as_uuid:
             def process(value):
@@ -212,21 +212,21 @@ class UUID(sqltypes.TypeEngine):
             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.
 
@@ -248,18 +248,18 @@ class ARRAY(sqltypes.MutableType, sqltypes.Concatenable, sqltypes.TypeEngine):
           notes for :class:`.MutableType` regarding ORM 
           performance implications (default changed from ``True`` in 
           0.7.0).
-          
+
           .. note:: This functionality is now superceded 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) "
@@ -273,7 +273,7 @@ class ARRAY(sqltypes.MutableType, sqltypes.Concatenable, sqltypes.TypeEngine):
                 "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
@@ -343,7 +343,7 @@ 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))
@@ -355,7 +355,7 @@ class ENUM(sqltypes.Enum):
         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)
 
@@ -406,7 +406,7 @@ ischema_names = {
 
 
 class PGCompiler(compiler.SQLCompiler):
-    
+
     def visit_match_op(self, binary, **kw):
         return "%s @@ to_tsquery(%s)" % (
                         self.process(binary.left), 
@@ -472,7 +472,7 @@ class PGCompiler(compiler.SQLCompiler):
             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), 
@@ -480,7 +480,7 @@ class PGCompiler(compiler.SQLCompiler):
                     result_map=self.result_map) 
                 for c in expression._select_iterables(returning_cols)
             ]
-            
+
         return 'RETURNING ' + ', '.join(columns)
 
     def visit_extract(self, extract, **kwargs):
@@ -489,7 +489,7 @@ class PGCompiler(compiler.SQLCompiler):
             affinity = extract.expr.type._type_affinity
         else:
             affinity = None
-        
+
         casts = {
                     sqltypes.Date:'date', 
                     sqltypes.DateTime:'timestamp', 
@@ -530,7 +530,7 @@ class PGDDLCompiler(compiler.DDLCompiler):
 
     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)
@@ -542,7 +542,7 @@ class PGDDLCompiler(compiler.DDLCompiler):
         return "DROP TYPE %s" % (
             self.preparer.format_type(type_)
         )
-        
+
     def visit_create_index(self, create):
         preparer = self.preparer
         index = create.element
@@ -555,7 +555,7 @@ class PGDDLCompiler(compiler.DDLCompiler):
                    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(
@@ -565,7 +565,7 @@ class PGDDLCompiler(compiler.DDLCompiler):
             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)
@@ -588,25 +588,25 @@ class PGTypeCompiler(compiler.GenericTypeCompiler):
             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)" % 
@@ -635,7 +635,7 @@ class PGTypeCompiler(compiler.GenericTypeCompiler):
 
     def visit_large_binary(self, type_):
         return self.visit_BYTEA(type_)
-        
+
     def visit_BYTEA(self, type_):
         return "BYTEA"
 
@@ -656,12 +656,12 @@ class PGIdentifierPreparer(compiler.IdentifierPreparer):
     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):
@@ -716,27 +716,27 @@ class PGExecutionContext(default.DefaultExecutionContext):
                 return self._execute_scalar(exc)
 
         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
@@ -776,7 +776,7 @@ class PGDialect(default.DefaultDialect):
             return connect
         else:
             return None
-            
+
     def do_begin_twophase(self, connection, xid):
         self.do_begin(connection.connection)
 
@@ -1056,24 +1056,24 @@ class PGDialect(default.DefaultDialect):
         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 = {}
-                
+
             if attype == 'numeric':
                 if charlen:
                     prec, scale = charlen.split(',')
@@ -1105,7 +1105,7 @@ class PGDialect(default.DefaultDialect):
                 args = (int(charlen),)
             else:
                 args = ()
-            
+
             while True:
                 if attype in self.ischema_names:
                     coltype = self.ischema_names[attype]
@@ -1132,7 +1132,7 @@ class PGDialect(default.DefaultDialect):
                 else:
                     coltype = None
                     break
-                
+
             if coltype:
                 coltype = coltype(*args, **kwargs)
                 if is_array:
@@ -1183,7 +1183,7 @@ class PGDialect(default.DefaultDialect):
     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'))
 
index 2187092e5dec623d5b91a0067ae39506a3c76e71..d3c2f1d50c1c7d7e81b981630159925ff945b69f 100644 (file)
@@ -76,27 +76,27 @@ class PGIdentifierPreparer_pg8000(PGIdentifierPreparer):
         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
-    
+
     colspecs = util.update_copy(
         PGDialect.colspecs,
         {
             sqltypes.Numeric : _PGNumeric,
         }
     )
-    
+
     @classmethod
     def dbapi(cls):
         return __import__('pg8000').dbapi
index 75cf53fda7a2d58f3c9de82e0e4abd48eef6824d..411bd42bd3a18fe927ae0d8d5345ef0146fe4542 100644 (file)
@@ -157,7 +157,7 @@ SERVER_SIDE_CURSOR_RE = re.compile(
 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 (
@@ -185,7 +185,7 @@ class PGExecutionContext_psycopg2(PGExecutionContext):
         # TODO: ouch
         if logger.isEnabledFor(logging.INFO):
             self._log_notices(self.cursor)
-        
+
         if self.__is_server_side:
             return base.BufferedRowResultProxy(self)
         else:
@@ -203,7 +203,7 @@ class PGExecutionContext_psycopg2(PGExecutionContext):
 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('%', '%%')
 
@@ -237,12 +237,12 @@ class PGDialect_psycopg2(PGDialect):
         self.server_side_cursors = server_side_cursors
         self.use_native_unicode = use_native_unicode
         self.supports_unicode_binds = use_native_unicode
-        
+
     @classmethod
     def dbapi(cls):
         psycopg = __import__('psycopg2')
         return psycopg
-    
+
     def on_connect(self):
         if self.isolation_level is not None:
             extensions = __import__('psycopg2.extensions').extensions
@@ -251,7 +251,7 @@ class PGDialect_psycopg2(PGDialect):
             'READ_UNCOMMITTED':extensions.ISOLATION_LEVEL_READ_UNCOMMITTED, 
             'REPEATABLE_READ':extensions.ISOLATION_LEVEL_REPEATABLE_READ,
             'SERIALIZABLE':extensions.ISOLATION_LEVEL_SERIALIZABLE
-            
+
             }
             def base_on_connect(conn):
                 try:
@@ -262,7 +262,7 @@ class PGDialect_psycopg2(PGDialect):
                                 self.isolation_level)
         else:
             base_on_connect = None
-            
+
         if self.dbapi and self.use_native_unicode:
             extensions = __import__('psycopg2.extensions').extensions
             def connect(conn):
@@ -292,4 +292,4 @@ class PGDialect_psycopg2(PGDialect):
             return False
 
 dialect = PGDialect_psycopg2
-    
+
index 6e050304d07dd095b563ed3fed015bc6bfcc9bc0..c52668762b90354ea17a06e0c981a4202d17b360 100644 (file)
@@ -65,22 +65,22 @@ from sqlalchemy import processors
 from sqlalchemy.types import BLOB, BOOLEAN, CHAR, DATE, DATETIME, DECIMAL,\
                             FLOAT, 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):
     _storage_format = "%04d-%02d-%02d %02d:%02d:%02d.%06d"
-  
+
     def bind_processor(self, dialect):
         datetime_datetime = datetime.datetime
         datetime_date = datetime.date
@@ -122,7 +122,7 @@ class DATE(_DateTimeMixin, sqltypes.Date):
                 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(
@@ -146,7 +146,7 @@ class TIME(_DateTimeMixin, sqltypes.Time):
                 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(
@@ -200,10 +200,10 @@ class SQLiteCompiler(compiler.SQLCompiler):
 
     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)
@@ -252,7 +252,7 @@ class SQLiteDDLCompiler(compiler.DDLCompiler):
              isinstance(column.type, sqltypes.Integer) and \
              not column.foreign_keys:
              colspec += " PRIMARY KEY AUTOINCREMENT"
-            
+
         return colspec
 
     def visit_primary_key_constraint(self, constraint):
@@ -269,12 +269,12 @@ class SQLiteDDLCompiler(compiler.DDLCompiler):
  
         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:
@@ -282,7 +282,7 @@ class SQLiteDDLCompiler(compiler.DDLCompiler):
 
     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):
@@ -347,7 +347,7 @@ class SQLiteExecutionContext(default.DefaultExecutionContext):
                     trunc_col = colname.split(".")[1]
                     rp._metadata._set_keymap_synonym(trunc_col, colname)
         return rp
-    
+
 class SQLiteDialect(default.DefaultDialect):
     name = 'sqlite'
     supports_alter = False
@@ -356,7 +356,7 @@ class SQLiteDialect(default.DefaultDialect):
     supports_default_values = True
     supports_empty_insert = False
     supports_cast = True
-    
+
     default_paramstyle = 'qmark'
     statement_compiler = SQLiteCompiler
     ddl_compiler = SQLiteDDLCompiler
@@ -366,7 +366,7 @@ class SQLiteDialect(default.DefaultDialect):
     colspecs = colspecs
     isolation_level = None
     execution_ctx_cls = SQLiteExecutionContext
-    
+
     supports_cast = True
     supports_default_values = True
 
@@ -378,7 +378,7 @@ class SQLiteDialect(default.DefaultDialect):
                 "Valid isolation levels for sqlite are 'SERIALIZABLE' and "
                 "'READ UNCOMMITTED'.")
         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 
@@ -391,14 +391,14 @@ class SQLiteDialect(default.DefaultDialect):
             self.supports_cast = \
                                 self.dbapi.sqlite_version_info >= (3, 2, 3)
 
-        
+
     def on_connect(self):
         if self.isolation_level is not None:
             if self.isolation_level == 'READ UNCOMMITTED':
                 isolation_level = 1
             else:
                 isolation_level = 0
-                
+
             def connect(conn):
                 cursor = conn.cursor()
                 cursor.execute("PRAGMA read_uncommitted = %d" % isolation_level)
@@ -439,7 +439,7 @@ class SQLiteDialect(default.DefaultDialect):
         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:
@@ -626,7 +626,7 @@ class SQLiteDialect(default.DefaultDialect):
 
 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
index 261ddffe2954b94e183fb9050237767a3997bc14..14cfa93d9507c178112030605b766834a8aa19bc 100644 (file)
@@ -36,20 +36,20 @@ The file specification for the SQLite database is taken as the "database" portio
 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.  
+To use a Windows path, regular drive specifications and backslashes can be used.
 Double backslashes are probably needed::
 
     # absolute path on Windows
@@ -117,7 +117,7 @@ implementation suitable:
   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
@@ -150,7 +150,7 @@ class _SQLite_pysqliteTimeStamp(DATETIME):
             return None
         else:
             return DATETIME.bind_processor(self, dialect)
-            
+
     def result_processor(self, dialect, coltype):
         if dialect.native_datetime:
             return None
@@ -163,7 +163,7 @@ class _SQLite_pysqliteDate(DATE):
             return None
         else:
             return DATE.bind_processor(self, dialect)
-            
+
     def result_processor(self, dialect, coltype):
         if dialect.native_datetime:
             return None
@@ -180,12 +180,12 @@ class SQLiteDialect_pysqlite(SQLiteDialect):
             sqltypes.TIMESTAMP:_SQLite_pysqliteTimeStamp,
         }
     )
-    
+
     # Py3K
     #description_encoding = None
-    
+
     driver = 'pysqlite'
-    
+
     def __init__(self, **kwargs):
         SQLiteDialect.__init__(self, **kwargs)
 
index 0668dcc562a45094638280261405cceb8dfa5442..3c4706043b4f760cf21f85be649c6c793098d05a 100644 (file)
@@ -88,10 +88,10 @@ RESERVED_WORDS = set([
     "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:
@@ -99,7 +99,7 @@ class _SybaseUnitypeMixin(object):
             else:
                 return None
         return process
-    
+
 class UNICHAR(_SybaseUnitypeMixin, sqltypes.Unicode):
     __visit_name__ = 'UNICHAR'
 
@@ -114,7 +114,7 @@ class TINYINT(sqltypes.Integer):
 
 class BIT(sqltypes.TypeEngine):
     __visit_name__ = 'BIT'
-    
+
 class MONEY(sqltypes.TypeEngine):
     __visit_name__ = "MONEY"
 
@@ -123,7 +123,7 @@ class SMALLMONEY(sqltypes.TypeEngine):
 
 class UNIQUEIDENTIFIER(sqltypes.TypeEngine):
     __visit_name__ = "UNIQUEIDENTIFIER"
-  
+
 class IMAGE(sqltypes.LargeBinary):
     __visit_name__ = 'IMAGE'
  
@@ -131,7 +131,7 @@ class IMAGE(sqltypes.LargeBinary):
 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_)
 
@@ -149,7 +149,7 @@ class SybaseTypeCompiler(compiler.GenericTypeCompiler):
 
     def visit_TINYINT(self, type_):
         return "TINYINT"
-        
+
     def visit_IMAGE(self, type_):
         return "IMAGE"
 
@@ -158,13 +158,13 @@ class SybaseTypeCompiler(compiler.GenericTypeCompiler):
 
     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
@@ -194,31 +194,31 @@ ischema_names = {
 
 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))
@@ -238,15 +238,15 @@ class SybaseExecutionContext(default.DefaultExecutionContext):
             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" %  
+                        "SET IDENTITY_INSERT %s OFF" %
                             self.dialect.identifier_preparer.
                             format_table(self.compiled.statement.table)
                         )
@@ -395,7 +395,7 @@ class SybaseDialect(default.DefaultDialect):
             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:
index 025b33743502eb40ca66c343c0f8ff4f6d4a83dc..c8480cb437b9d23665b117360d0797567d47f530 100644 (file)
@@ -31,7 +31,7 @@ Currently *not* supported are::
     UNICHAR
     UNITEXT
     UNIVARCHAR
-    
+
 """
 
 from sqlalchemy.dialects.sybase.base import SybaseDialect,\
@@ -42,11 +42,11 @@ 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):
index d6f5c3b6b93ef8132b2109478ca715a349180be7..fed7928172c1340c1c7d9190ba519997361f2871 100644 (file)
@@ -54,7 +54,7 @@ class SybaseExecutionContext_pysybase(SybaseExecutionContext):
 class SybaseSQLCompiler_pysybase(SybaseSQLCompiler):
     def bindparam_string(self, name):
         return "@" + name
-   
+
 class SybaseDialect_pysybase(SybaseDialect):
     driver = 'pysybase'
     execution_ctx_cls = SybaseExecutionContext_pysybase
index c26b65e08dc4e372e804f3e16073695f72289766..1ca15f7fb14114339f0b5b66152f38878bf41ed1 100644 (file)
@@ -5,20 +5,20 @@ Rules for Migrating TypeEngine classes to 0.6
 
     a. Specifying behavior which needs to occur for bind parameters
     or result row columns.
-    
+
     b. Specifying types that are entirely specific to the database
     in use and have no analogue in the sqlalchemy.types package.
-    
+
     c. Specifying types where there is an analogue in sqlalchemy.types,
     but the database in use takes vendor-specific flags for those
     types.
 
     d. If a TypeEngine class doesn't provide any of this, it should be
     *removed* from the dialect.
-    
+
 2. the TypeEngine classes are *no longer* used for generating DDL.  Dialects
 now have a TypeCompiler subclass which uses the same visit_XXX model as
-other compilers.   
+other compilers.
 
 3. the "ischema_names" and "colspecs" dictionaries are now required members on
 the Dialect class.
@@ -29,7 +29,7 @@ the current mixed case naming can remain, i.e. _PGNumeric for Numeric - in this
 end users would never need to use _PGNumeric directly.   However, if a dialect-specific 
 type is specifying a type *or* arguments that are not present generically, it should
 match the real name of the type on that backend, in uppercase.  E.g. postgresql.INET,
-mysql.ENUM, postgresql.ARRAY.  
+mysql.ENUM, postgresql.ARRAY.
 
 Or follow this handy flowchart:
 
@@ -61,8 +61,8 @@ Or follow this handy flowchart:
                                                               |
                                                               v
                                                         the type should
-                                                        subclass the   
-                                                        UPPERCASE      
+                                                        subclass the
+                                                        UPPERCASE
                                                         type in types.py
                                                         (i.e. class BLOB(types.BLOB))
 
@@ -86,14 +86,14 @@ MySQL names it SET in the dialect's base.py, and it subclasses types.String, sin
 it ultimately deals with strings.
 
 Example 5.  Postgresql has a DATETIME type.  The DBAPIs handle dates correctly,
-and no special arguments are used in PG's DDL beyond what types.py provides.  
+and no special arguments are used in PG's DDL beyond what types.py provides.
 Postgresql dialect therefore imports types.DATETIME into its base.py.
 
 Ideally one should be able to specify a schema using names imported completely from a 
 dialect, all matching the real name on that backend:
 
    from sqlalchemy.dialects.postgresql import base as pg
-   
+
    t = Table('mytable', metadata,
               Column('id', pg.INTEGER, primary_key=True),
               Column('name', pg.VARCHAR(300)),
@@ -110,7 +110,7 @@ indicate a special type only available in this database, it must be *removed* fr
 module and from this dictionary.
 
 6. "ischema_names" indicates string descriptions of types as returned from the database
-linked to TypeEngine classes.   
+linked to TypeEngine classes.
 
     a. The string name should be matched to the most specific type possible within
     sqlalchemy.types, unless there is no matching type within sqlalchemy.types in which
@@ -118,28 +118,28 @@ linked to TypeEngine classes.
     own subclass of that type with special bind/result behavior - reflect to the types.py
     UPPERCASE type as much as possible.   With very few exceptions, all types
     should reflect to an UPPERCASE type.
-    
+
     b. If the dialect contains a matching dialect-specific type that takes extra arguments 
     which the generic one does not, then point to the dialect-specific type.  E.g.
     mssql.VARCHAR takes a "collation" parameter which should be preserved.
-    
+
 5. DDL, or what was formerly issued by "get_col_spec()", is now handled exclusively by
 a subclass of compiler.GenericTypeCompiler.
 
     a. your TypeCompiler class will receive generic and uppercase types from 
     sqlalchemy.types.  Do not assume the presence of dialect-specific attributes on
     these types. 
-    
+
     b. the visit_UPPERCASE methods on GenericTypeCompiler should *not* be overridden with
     methods that produce a different DDL name.   Uppercase types don't do any kind of 
     "guessing" - if visit_TIMESTAMP is called, the DDL should render as TIMESTAMP in
     all cases, regardless of whether or not that type is legal on the backend database.
-    
+
     c. the visit_UPPERCASE methods *should* be overridden with methods that add additional
-    arguments and flags to those types.  
-    
+    arguments and flags to those types.
+
     d. the visit_lowercase methods are overridden to provide an interpretation of a generic 
     type.  E.g.  visit_large_binary() might be overridden to say "return self.visit_BIT(type_)".
-    
+
     e. visit_lowercase methods should *never* render strings directly - it should always
     be via calling a visit_UPPERCASE() method.
index 9dd7f0653ed84ed9ab20790ca63f09bab0acf404..aebf3543655a671bdd6ba667c8e72bba0734d009 100644 (file)
@@ -51,7 +51,7 @@ url.py
 """
 
 # not sure what this was used for
-#import sqlalchemy.databases  
+#import sqlalchemy.databases
 
 from sqlalchemy.engine.base import (
     BufferedColumnResultProxy,
@@ -174,17 +174,17 @@ def create_engine(*args, **kwargs):
     :param execution_options: Dictionary execution options which will
         be applied to all connections.  See
         :meth:`~sqlalchemy.engine.base.Connection.execution_options`
-        
+
     :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 
@@ -246,7 +246,7 @@ def create_engine(*args, **kwargs):
     :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)
index 49355bf65f68bc90f9380f4b9c5550ef0e09a764..eb48c29d61dfac102cb26a526ab7d92b37e0603b 100644 (file)
@@ -71,19 +71,19 @@ class Dialect(object):
       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.
@@ -115,7 +115,7 @@ class Dialect(object):
       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,
@@ -123,7 +123,7 @@ class Dialect(object):
       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
@@ -143,17 +143,17 @@ class Dialect(object):
     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
@@ -163,7 +163,7 @@ class Dialect(object):
       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):
@@ -172,7 +172,7 @@ class Dialect(object):
         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()
@@ -187,7 +187,7 @@ class Dialect(object):
 
         The returned result is cached *per dialect class* so can
         contain no dialect-instance state.
-        
+
         """
 
         raise NotImplementedError()
@@ -198,13 +198,13 @@ class Dialect(object):
 
         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
@@ -217,12 +217,12 @@ class Dialect(object):
         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()
@@ -356,7 +356,7 @@ class Dialect(object):
     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.
 
@@ -366,13 +366,13 @@ class Dialect(object):
     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.
 
@@ -396,15 +396,15 @@ class Dialect(object):
 
     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.
@@ -412,7 +412,7 @@ class Dialect(object):
         This is used by the default implementation to populate the
         "default_schema_name" attribute and is called exactly
         once upon first connect.
-        
+
         """
 
         raise NotImplementedError()
@@ -512,7 +512,7 @@ class Dialect(object):
 
         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.
 
@@ -645,7 +645,7 @@ class ExecutionContext(object):
         in some dialects; this is indicated by the 
         ``supports_sane_rowcount`` and ``supports_sane_multi_rowcount``
         dialect attributes.
-        
+
         """
 
         raise NotImplementedError()
@@ -691,13 +691,13 @@ class Compiled(object):
     @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)
 
@@ -705,7 +705,7 @@ class Compiled(object):
         """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.
 
@@ -793,7 +793,7 @@ class Connection(Connectable):
     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
@@ -803,9 +803,9 @@ class Connection(Connectable):
 
     .. index::
       single: thread safety; Connection
-      
+
     """
-    
+
     def __init__(self, engine, connection=None, close_with_result=False,
                  _branch=False, _execution_options=None):
         """Construct a new Connection.
@@ -813,7 +813,7 @@ class Connection(Connectable):
         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
@@ -850,21 +850,21 @@ class Connection(Connectable):
         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)
-            
+
         The options are the same as those accepted by 
         :meth:`sqlalchemy.sql.expression.Executable.execution_options`.
 
@@ -872,7 +872,7 @@ class Connection(Connectable):
         c = self._clone()
         c._execution_options = c._execution_options.union(opt)
         return c
-    
+
     @property
     def closed(self):
         """Return True if this connection is closed."""
@@ -894,7 +894,7 @@ class Connection(Connectable):
             return self.__connection
         except AttributeError:
             return self._revalidate_connection()
-        
+
     def _revalidate_connection(self):
         if self.__invalid:
             if self.__transaction is not None:
@@ -905,13 +905,13 @@ class Connection(Connectable):
             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
@@ -960,7 +960,7 @@ class Connection(Connectable):
         """
         if self.invalidated:
             return
-            
+
         if self.closed:
             raise exc.ResourceClosedError("This Connection is closed")
 
@@ -968,8 +968,8 @@ class Connection(Connectable):
             self.__connection.invalidate(exception)
         del self.__connection
         self.__invalid = True
-    
-        
+
+
     def detach(self):
         """Detach the underlying DB-API connection from its connection pool.
 
@@ -1140,7 +1140,7 @@ class Connection(Connectable):
         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.
 
@@ -1151,9 +1151,9 @@ class Connection(Connectable):
 
     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 
@@ -1164,7 +1164,7 @@ class Connection(Connectable):
         * a :class:`.DDLElement` object
         * a :class:`.DefaultGenerator` object
         * a :class:`.Compiled` object
-            
+
         """
 
         for c in type(object).__mro__:
@@ -1186,7 +1186,7 @@ class Connection(Connectable):
 
         In the case of 'raw' execution which accepts positional parameters,
         it may be a list of tuples or lists.
-        
+
         """
 
         if not multiparams:
@@ -1219,28 +1219,28 @@ class Connection(Connectable):
 
     def _execute_default(self, default, multiparams, params):
         """Execute a schema.ColumnDefault object."""
-        
+
         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)
         if self.should_close_with_result:
             self.close()
         return ret
-    
+
     def _execute_ddl(self, ddl, params, multiparams):
         """Execute a schema.DDL object."""
-        
+
         dialect = self.dialect
         return self._execute_context(
             dialect,
@@ -1252,7 +1252,7 @@ class Connection(Connectable):
 
     def _execute_clauseelement(self, elem, multiparams, params):
         """Execute a sql.ClauseElement object."""
-        
+
         params = self.__distill_params(multiparams, params)
         if params:
             keys = params[0].keys()
@@ -1298,7 +1298,7 @@ class Connection(Connectable):
 
     def _execute_text(self, statement, multiparams, params):
         """Execute a string SQL statement."""
-        
+
         dialect = self.dialect
         parameters = self.__distill_params(multiparams, params)
         return self._execute_context(
@@ -1316,13 +1316,13 @@ class Connection(Connectable):
                                     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, 
@@ -1332,14 +1332,14 @@ class Connection(Connectable):
 
         if context.compiled:
             context.pre_exec()
-            
+
         cursor, statement, parameters = context.cursor, \
                                         context.statement, \
                                         context.parameters
-                                        
+
         if not context.executemany:
             parameters = parameters[0]
-                
+
         if self._before_cursor_execute:
             statement, parameters = self._before_cursor_execute(
                                             context,
@@ -1376,13 +1376,13 @@ class Connection(Connectable):
         if self._after_cursor_execute:
             self._after_cursor_execute(context, cursor, 
                                         statement, parameters)
-            
+
         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()
@@ -1399,25 +1399,25 @@ class Connection(Connectable):
             # 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.   
+        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)
@@ -1439,7 +1439,7 @@ class Connection(Connectable):
     def _safe_close_cursor(self, cursor):
         """Close the given cursor, catching exceptions
         and turning into log warnings.
-        
+
         """
         try:
             cursor.close()
@@ -1452,7 +1452,7 @@ class Connection(Connectable):
 
             if isinstance(e, (SystemExit, KeyboardInterrupt)):
                 raise
-        
+
     def _handle_dbapi_exception(self, 
                                     e, 
                                     statement, 
@@ -1499,7 +1499,7 @@ class Connection(Connectable):
                                     connection_invalidated=is_disconnect), \
                                     None, sys.exc_info()[2]
             # end Py2K
-            
+
         finally:
             del self._reentrant_error
 
@@ -1538,9 +1538,9 @@ class Connection(Connectable):
         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()
@@ -1564,7 +1564,7 @@ class Transaction(object):
     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::
@@ -1575,7 +1575,7 @@ class Transaction(object):
         """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
@@ -1590,7 +1590,7 @@ class Transaction(object):
 
         This is used to cancel a Transaction without affecting the scope of
         an enclosing transaction.
-        
+
         """
         if not self._parent.is_active:
             return
@@ -1599,7 +1599,7 @@ class Transaction(object):
 
     def rollback(self):
         """Roll back this :class:`.Transaction`.
-        
+
         """
         if not self._parent.is_active:
             return
@@ -1611,7 +1611,7 @@ class Transaction(object):
 
     def commit(self):
         """Commit this :class:`.Transaction`."""
-        
+
         if not self._parent.is_active:
             raise exc.InvalidRequestError("This transaction is inactive")
         self._do_commit()
@@ -1679,13 +1679,13 @@ class TwoPhaseTransaction(Transaction):
     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.
 
@@ -1693,7 +1693,7 @@ class Engine(Connectable, log.Identified):
 
     _execution_options = util.frozendict()
     Connection = Connection
-    
+
     def __init__(self, pool, dialect, url, 
                         logging_name=None, echo=None, proxy=None,
                         execution_options=None
@@ -1711,17 +1711,17 @@ class Engine(Connectable, log.Identified):
         if execution_options:
             self.update_execution_options(**execution_options)
 
-            
+
     dispatch = event.dispatcher(events.EngineEvents)
-    
+
     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)
@@ -1751,23 +1751,23 @@ class Engine(Connectable, log.Identified):
         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.   
-        
+        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.   
+        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()
@@ -1804,11 +1804,11 @@ class Engine(Connectable, log.Identified):
     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)
@@ -1832,13 +1832,13 @@ class Engine(Connectable, log.Identified):
         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)
@@ -1854,10 +1854,10 @@ class Engine(Connectable, log.Identified):
 
     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
@@ -1865,7 +1865,7 @@ class Engine(Connectable, log.Identified):
         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)
@@ -1884,29 +1884,29 @@ class Engine(Connectable, log.Identified):
 
     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(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.  
+          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(self, 
@@ -1960,25 +1960,25 @@ class Engine(Connectable, log.Identified):
 def _listener_connection_cls(cls, dispatch):
     """Produce a wrapper for :class:`.Connection` which will apply event 
     dispatch to each method.
-    
+
     :class:`.Connection` does not provide event dispatch built in so that
     method call overhead is avoided in the absense of any listeners.
-    
+
     """
     class EventListenerConnection(cls):
         def execute(self, clauseelement, *multiparams, **params):
             for fn in dispatch.before_execute:
                 clauseelement, multiparams, params = \
                     fn(self, clauseelement, multiparams, params)
-            
+
             ret = super(EventListenerConnection, self).\
                     execute(clauseelement, *multiparams, **params)
 
             for fn in dispatch.after_execute:
                 fn(self, clauseelement, multiparams, params, ret)
-            
+
             return ret
-            
+
         def _execute_clauseelement(self, clauseelement, 
                                     multiparams=None, params=None):
             return self.execute(clauseelement, 
@@ -1992,7 +1992,7 @@ def _listener_connection_cls(cls, dispatch):
                             fn(self, cursor, statement, parameters, 
                                         context, context.executemany)
             return statement, parameters
-        
+
         def _after_cursor_execute(self, context, cursor, 
                                             statement, parameters):
             dispatch.after_cursor_execute(self, cursor, 
@@ -2000,12 +2000,12 @@ def _listener_connection_cls(cls, dispatch):
                                                 parameters, 
                                                 context, 
                                                 context.executemany)
-            
+
         def _begin_impl(self):
             dispatch.begin(self)
             return super(EventListenerConnection, self).\
                         _begin_impl()
-            
+
         def _rollback_impl(self):
             dispatch.rollback(self)
             return super(EventListenerConnection, self).\
@@ -2020,17 +2020,17 @@ def _listener_connection_cls(cls, dispatch):
             dispatch.savepoint(self, name)
             return super(EventListenerConnection, self).\
                         _savepoint_impl(name=name)
-                
+
         def _rollback_to_savepoint_impl(self, name, context):
             dispatch.rollback_savepoint(self, name, context)
             return super(EventListenerConnection, self).\
                         _rollback_to_savepoint_impl(name, context)
-            
+
         def _release_savepoint_impl(self, name, context):
             dispatch.release_savepoint(self, name, context)
             return super(EventListenerConnection, self).\
                         _release_savepoint_impl(name, context)
-            
+
         def _begin_twophase_impl(self, xid):
             dispatch.begin_twophase(self, xid)
             return super(EventListenerConnection, self).\
@@ -2203,12 +2203,12 @@ try:
     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 = []
 
@@ -2224,7 +2224,7 @@ class ResultMetaData(object):
         for i, rec in enumerate(metadata):
             colname = rec[0]
             coltype = rec[1]
-            
+
             if dialect.description_encoding:
                 colname = dialect._description_decoder(colname)
 
@@ -2239,14 +2239,14 @@ class ResultMetaData(object):
                         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
@@ -2257,7 +2257,7 @@ class ResultMetaData(object):
 
             if dialect.requires_name_normalize:
                 colname = dialect.normalize_name(colname)
-                
+
             self.keys.append(colname)
             if obj:
                 for o in obj:
@@ -2266,19 +2266,19 @@ class ResultMetaData(object):
         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
@@ -2318,7 +2318,7 @@ class ResultMetaData(object):
             ),
             'keys': self.keys
         }
-    
+
     def __setstate__(self, state):
         # the row has been processed at pickling time so we don't need any
         # processor anymore
@@ -2329,7 +2329,7 @@ class ResultMetaData(object):
         self.keys = state['keys']
         self._echo = False
 
-       
+
 class ResultProxy(object):
     """Wraps a DB-API cursor object to provide easier access to row columns.
 
@@ -2354,7 +2354,7 @@ class ResultProxy(object):
     _process_row = RowProxy
     out_parameters = None
     _can_close_connection = False
-    
+
     def __init__(self, context):
         self.context = context
         self.dialect = context.dialect
@@ -2371,23 +2371,23 @@ class ResultProxy(object):
             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()`
@@ -2395,37 +2395,37 @@ class ResultProxy(object):
         :meth:`~sqlalchemy.engine.base.ResultProxy.supports_sane_multi_rowcount()`.
         ``rowcount()`` also may not work at this time for a statement that
         uses ``returning()``.
-        
+
         """
         return self.context.rowcount
 
     @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.
-        
+
         """
         return self._saved_cursor.lastrowid
-    
+
     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.
 
@@ -2437,7 +2437,7 @@ class ResultProxy(object):
 
         * all result rows are exhausted using the fetchXXX() methods.
         * cursor.description is None.
-        
+
         """
 
         if not self.closed:
@@ -2448,7 +2448,7 @@ class ResultProxy(object):
                 self.connection.close()
             # allow consistent errors
             self.cursor = None
-            
+
     def __iter__(self):
         while True:
             row = self.fetchone()
@@ -2456,11 +2456,11 @@ class ResultProxy(object):
                 raise StopIteration
             else:
                 yield row
-    
+
     @util.memoized_property
     def inserted_primary_key(self):
         """Return the primary key for the row just inserted.
-        
+
         This only applies to single row insert() constructs which
         did not explicitly specify returning().
 
@@ -2473,19 +2473,19 @@ class ResultProxy(object):
             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
@@ -2495,7 +2495,7 @@ class ResultProxy(object):
     def last_inserted_params(self):
         """Return the collection of inserted parameters from this
         execution.
-        
+
         """
         if self.context.executemany:
             return self.context.compiled_parameters
@@ -2549,7 +2549,7 @@ class ResultProxy(object):
             return self.cursor.fetchall()
         except AttributeError:
             self._non_result()
-    
+
     def _non_result(self):
         if self._metadata is None:
             raise exc.ResourceClosedError(
@@ -2558,7 +2558,7 @@ class ResultProxy(object):
             )
         else:
             raise exc.ResourceClosedError("This result object is closed.")
-        
+
     def process_rows(self, rows):
         process_row = self._process_row
         metadata = self._metadata
@@ -2591,10 +2591,10 @@ class ResultProxy(object):
     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:
@@ -2610,10 +2610,10 @@ class ResultProxy(object):
 
     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()
@@ -2630,9 +2630,9 @@ class ResultProxy(object):
 
     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()
@@ -2652,12 +2652,12 @@ class ResultProxy(object):
                 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:
@@ -2726,11 +2726,11 @@ class BufferedRowResultProxy(ResultProxy):
 
 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()
@@ -2738,7 +2738,7 @@ class FullyBufferedResultProxy(ResultProxy):
 
     def _buffer_rows(self):
         return self.cursor.fetchall()
-        
+
     def _fetchone_impl(self):
         if self.__rowbuffer:
             return self.__rowbuffer.pop(0)
@@ -2772,7 +2772,7 @@ class BufferedColumnRow(RowProxy):
         row = tuple(row)
         super(BufferedColumnRow, self).__init__(parent, row,
                                                 processors, keymap)
-        
+
 class BufferedColumnResultProxy(ResultProxy):
     """A ResultProxy with column buffering behavior.
 
@@ -2782,7 +2782,7 @@ class BufferedColumnResultProxy(ResultProxy):
     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
index 10c7d55f2f6a4996535dd859155fb71d0ccf59aa..6b5684f641189c0a325a75736cc34aaaa95a4266 100644 (file)
@@ -34,20 +34,20 @@ class SchemaGenerator(DDLBase):
         else:
             tables = metadata.tables.values()
         collection = [t for t in sql_util.sort_tables(tables) if self._can_create(t)]
-        
+
         metadata.dispatch.before_create(metadata, self.connection,
                                     tables=collection)
-        
+
         for table in collection:
             self.traverse_single(table, create_ok=True)
-            
+
         metadata.dispatch.after_create(metadata, self.connection,
                                     tables=collection)
 
     def visit_table(self, table, create_ok=False):
         if not create_ok and not self._can_create(table):
             return
-        
+
         table.dispatch.before_create(table, self.connection)
 
         for column in table.columns:
@@ -88,10 +88,10 @@ class SchemaDropper(DDLBase):
         else:
             tables = metadata.tables.values()
         collection = [t for t in reversed(sql_util.sort_tables(tables)) if self._can_drop(t)]
-        
+
         metadata.dispatch.before_drop(metadata, self.connection,
                                             tables=collection)
-        
+
         for table in collection:
             self.traverse_single(table, drop_ok=True)
 
@@ -118,7 +118,7 @@ class SchemaDropper(DDLBase):
                 self.traverse_single(column.default)
 
         self.connection.execute(schema.DropTable(table))
-        
+
         table.dispatch.after_drop(table, self.connection)
 
     def visit_sequence(self, sequence):
index 8721b97aa180fe63ea255f9d515a9a1536bbb29d..76077778cef942566ed170c5aecbf78106847bc9 100644 (file)
@@ -34,23 +34,23 @@ class DefaultDialect(base.Dialect):
     supports_alter = True
 
     # most DBAPIs happy with this for execute().
-    # not cx_oracle.  
+    # not cx_oracle.
     execute_sequence_format = tuple
-    
+
     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
@@ -63,18 +63,18 @@ class DefaultDialect(base.Dialect):
 
 
     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 = {}
@@ -82,28 +82,28 @@ class DefaultDialect(base.Dialect):
     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" %
                 self.name)
-        
+
         self.convert_unicode = convert_unicode
         if assert_unicode:
             util.warn_deprecated(
@@ -114,7 +114,7 @@ class DefaultDialect(base.Dialect):
                 "received. "
                 "This does *not* apply to DBAPIs that coerce Unicode "
                 "natively.")
-            
+
         self.encoding = encoding
         self.positional = False
         self._ischema = None
@@ -137,32 +137,32 @@ class DefaultDialect(base.Dialect):
                     " maximum identifier length of %d" %
                     (label_length, self.max_identifier_length))
         self.label_length = label_length
-        
+
         if not hasattr(self, 'description_encoding'):
             self.description_encoding = getattr(
                                             self, 
                                             'description_encoding', 
                                             encoding)
-        
+
         if self.description_encoding:
             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 = \
@@ -176,23 +176,23 @@ class DefaultDialect(base.Dialect):
             self.default_schema_name = 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:
@@ -215,22 +215,22 @@ class DefaultDialect(base.Dialect):
                     )
                 )
                 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.
@@ -249,14 +249,14 @@ class DefaultDialect(base.Dialect):
     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(
@@ -332,11 +332,11 @@ class DefaultExecutionContext(base.ExecutionContext):
     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
@@ -356,7 +356,7 @@ class DefaultExecutionContext(base.ExecutionContext):
             self.statement = dialect._encoder(self.unicode_statement)[0]
         else:
             self.statement = self.unicode_statement = unicode(compiled)
-            
+
         self.cursor = self.create_cursor()
         self.compiled_parameters = []
 
@@ -366,7 +366,7 @@ class DefaultExecutionContext(base.ExecutionContext):
             self.parameters = [{}]
 
         return self
-        
+
     @classmethod
     def _init_compiled(cls, dialect, connection, dbapi_connection, compiled, parameters):
         """Initialize execution context for a Compiled construct."""
@@ -401,7 +401,7 @@ class DefaultExecutionContext(base.ExecutionContext):
         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 \
@@ -413,7 +413,7 @@ class DefaultExecutionContext(base.ExecutionContext):
             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()
@@ -421,7 +421,7 @@ class DefaultExecutionContext(base.ExecutionContext):
             self.__process_defaults()
             self.postfetch_cols = self.compiled.postfetch
             self.prefetch_cols = self.compiled.prefetch
-        
+
         processors = compiled._bind_processors
 
         # Convert the dictionary of bind parameter values 
@@ -456,9 +456,9 @@ class DefaultExecutionContext(base.ExecutionContext):
                             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."""
@@ -490,18 +490,18 @@ class DefaultExecutionContext(base.ExecutionContext):
         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."""
@@ -514,11 +514,11 @@ class DefaultExecutionContext(base.ExecutionContext):
         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', 
@@ -526,20 +526,20 @@ class DefaultExecutionContext(base.ExecutionContext):
                                                 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):
         """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
@@ -551,10 +551,10 @@ class DefaultExecutionContext(base.ExecutionContext):
             default_params = self.dialect.execute_sequence_format()
         else:
             default_params = {}
-            
+
         conn._cursor_execute(self.cursor, stmt, default_params)
         return self.cursor.fetchone()[0]
-    
+
     @property
     def connection(self):
         return self.root_connection._branch()
@@ -570,32 +570,32 @@ class DefaultExecutionContext(base.ExecutionContext):
 
     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
 
@@ -604,7 +604,7 @@ class DefaultExecutionContext(base.ExecutionContext):
 
     def get_result_proxy(self):
         return base.ResultProxy(self)
-    
+
     @property
     def rowcount(self):
         return self.cursor.rowcount
@@ -614,19 +614,19 @@ class DefaultExecutionContext(base.ExecutionContext):
 
     def supports_sane_multi_rowcount(self):
         return self.dialect.supports_sane_multi_rowcount
-    
+
     def post_insert(self):
         if 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()
             self.inserted_primary_key = [
                 c is table._autoincrement_column 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()
@@ -637,9 +637,9 @@ class DefaultExecutionContext(base.ExecutionContext):
                 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)
@@ -648,10 +648,10 @@ class DefaultExecutionContext(base.ExecutionContext):
         """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'):
@@ -696,12 +696,12 @@ class DefaultExecutionContext(base.ExecutionContext):
         elif default.is_clause_element:
             # TODO: expensive branching here should be 
             # pulled into _exec_scalar()
-            conn = self.connection  
+            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
@@ -713,7 +713,7 @@ class DefaultExecutionContext(base.ExecutionContext):
             return None
         else:
             return self._exec_default(column.onupdate)
-    
+
     def __process_defaults(self):
         """Generate default values for compiled insert/update statements,
         and generate inserted_primary_key collection.
@@ -722,7 +722,7 @@ class DefaultExecutionContext(base.ExecutionContext):
         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()
@@ -731,7 +731,7 @@ class DefaultExecutionContext(base.ExecutionContext):
                         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.compiled.prefetch:
@@ -757,7 +757,7 @@ class DefaultExecutionContext(base.ExecutionContext):
                 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) 
@@ -765,5 +765,5 @@ class DefaultExecutionContext(base.ExecutionContext):
                                                 statement.table.primary_key
                                 ]
 
-            
+
 DefaultDialect.execution_ctx_cls = DefaultExecutionContext
index 964e9fbeeef4f03dd615c948c1ac49adc14a59d0..cf254cba607c3d6ec0bdcee1d005f56ebdf11231 100644 (file)
@@ -55,17 +55,17 @@ class Inspector(object):
     :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):
@@ -75,7 +75,7 @@ class Inspector(object):
           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`
 
@@ -83,10 +83,10 @@ class Inspector(object):
 
         # ensure initialized
         bind.connect()
-        
+
         # 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
@@ -103,14 +103,14 @@ class Inspector(object):
           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)
@@ -120,10 +120,10 @@ class Inspector(object):
     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
 
@@ -174,9 +174,9 @@ class Inspector(object):
 
     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,
@@ -252,10 +252,10 @@ class Inspector(object):
 
         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.
 
@@ -265,7 +265,7 @@ class Inspector(object):
                                               **kw)
 
         return pkeys
-        
+
 
     def get_foreign_keys(self, table_name, schema=None, **kw):
         """Return information about foreign_keys in `table_name`.
@@ -288,7 +288,7 @@ class Inspector(object):
 
         name
           optional name of the foreign key constraint.
-          
+
         \**kw
           other options passed to the dialect's get_foreign_keys() method.
 
@@ -313,7 +313,7 @@ class Inspector(object):
 
         unique
           boolean
-          
+
         \**kw
           other options passed to the dialect's get_indexes() method.
         """
@@ -325,23 +325,23 @@ class Inspector(object):
 
     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
 
@@ -393,13 +393,13 @@ class Inspector(object):
                 col_kw['autoincrement'] = col_d['autoincrement']
             if 'quote' in col_d:
                 col_kw['quote'] = col_d['quote']
-                
+
             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'])))
-                
+
             if 'sequence' in col_d:
                 # TODO: mssql, maxdb and sybase are using this.
                 seq = col_d['sequence']
@@ -409,7 +409,7 @@ class Inspector(object):
                 if 'increment' in seq:
                     sequence.increment = seq['increment']
                 colargs.append(sequence)
-                
+
             col = sa_schema.Column(name, coltype, *colargs, **col_kw)
             table.append_column(col)
 
index df3d5b64ab942b75ae5a1d27835cc64490cf3f33..e49d0e99e63ec64556c11defccf6d833e63dc4a8 100644 (file)
@@ -28,7 +28,7 @@ class EngineStrategy(object):
 
     Provides a ``create`` method that receives input arguments and
     produces an instance of base.Engine or a subclass.
-    
+
     """
 
     def __init__(self):
@@ -85,7 +85,7 @@ class DefaultEngineStrategy(EngineStrategy):
                     import sys
                     raise exc.DBAPIError.instance(None, None, e), None, sys.exc_info()[2]
                     # end Py2K
-                    
+
             creator = kwargs.pop('creator', connect)
 
             poolclass = kwargs.pop('poolclass', None)
@@ -120,7 +120,7 @@ class DefaultEngineStrategy(EngineStrategy):
                 engine_args[k] = kwargs.pop(k)
 
         _initialize = kwargs.pop('_initialize', True)
-        
+
         # all kwargs should be consumed
         if kwargs:
             raise TypeError(
@@ -131,7 +131,7 @@ class DefaultEngineStrategy(EngineStrategy):
                                     dialect.__class__.__name__,
                                     pool.__class__.__name__,
                                     engineclass.__name__))
-                                    
+
         engine = engineclass(pool, dialect, u, **engine_args)
 
         if _initialize:
@@ -142,10 +142,10 @@ class DefaultEngineStrategy(EngineStrategy):
                     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)
                 dialect.initialize(c)
@@ -159,13 +159,13 @@ class PlainEngineStrategy(DefaultEngineStrategy):
 
     name = 'plain'
     engine_cls = base.Engine
-    
+
 PlainEngineStrategy()
 
 
 class ThreadLocalEngineStrategy(DefaultEngineStrategy):
     """Strategy for configuring an Engine with thredlocal behavior."""
-    
+
     name = 'threadlocal'
     engine_cls = threadlocal.TLEngine
 
@@ -177,11 +177,11 @@ class MockEngineStrategy(EngineStrategy):
 
     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)
@@ -218,7 +218,7 @@ class MockEngineStrategy(EngineStrategy):
         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):
index a083d0113d9c63b8dff4131ee4deba58c5ca98cf..2ce0922bf2416299c1a2f51435405b70815094a8 100644 (file)
@@ -19,11 +19,11 @@ 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)
@@ -52,21 +52,21 @@ class TLEngine(base.Engine):
         self._connections = util.threading.local()
 
     dispatch = event.dispatcher(TLEvents)
-    
+
     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.TLConnection(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 = []
@@ -76,42 +76,42 @@ class TLEngine(base.Engine):
         if not hasattr(self._connections, 'trans'):
             self._connections.trans = []
         self._connections.trans.append(self.contextual_connect().begin_nested())
-        
+
     def begin(self):
         if not hasattr(self._connections, 'trans'):
             self._connections.trans = []
         self._connections.trans.append(self.contextual_connect().begin())
-        
+
     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()
@@ -119,6 +119,6 @@ class TLEngine(base.Engine):
             connection._force_close()
             del self._connections.conn
             self._connections.trans = []
-        
+
     def __repr__(self):
         return 'TLEngine(%s)' % str(self.url)
index 199b37c46a5c303d23464d0b8fd88ad6e75bb538..9f4c2dbdf2269513ec1ed33c618e2d9385da26be 100644 (file)
@@ -113,25 +113,25 @@ class URL(object):
                 return module
             else:
                 raise
-    
+
     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.
 
index 3637234eee67acd109ccb8f96408df9249312d2c..6c74c101da9d423304e010a4a7cef5e0cc73ad18 100644 (file)
@@ -13,9 +13,9 @@ NO_RETVAL = util.symbol('NO_RETVAL')
 
 def listen(target, identifier, fn, *args, **kw):
     """Register a listener function for the given target.
-    
+
     """
-    
+
     for evt_cls in _registrars[identifier]:
         tgt = evt_cls._accept_with(target)
         if tgt is not None:
@@ -26,11 +26,11 @@ def listen(target, identifier, fn, *args, **kw):
 
 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):
@@ -41,42 +41,42 @@ _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):
         return _parent_cls.__dict__['dispatch'].dispatch_cls(_parent_cls)
-        
+
 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.   
+    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, )
-    
+
     @property
     def _descriptors(self):
         return (getattr(self, k) for k in dir(self) if _is_event_name(k))
@@ -87,20 +87,20 @@ class _Dispatch(object):
 
         for ls in other._descriptors:
             getattr(self, ls.name)._update(ls, only_propagate=only_propagate)
-            
-            
+
+
 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.
@@ -109,7 +109,7 @@ def _create_dispatcher_class(cls, classname, bases, dict_):
                                         (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]))
@@ -121,13 +121,13 @@ def _remove_dispatcher(cls):
             _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
@@ -144,42 +144,42 @@ class Events(object):
     @classmethod
     def _listen(cls, target, identifier, fn, propagate=False):
         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 append(self, obj, target, propagate):
         assert isinstance(target, type), \
                 "Class-level Event targets must be classes."
-                
+
         for cls in [target] + target.__subclasses__():
             self._clslevel[cls].append(obj)
-    
+
     def remove(self, obj, target):
         for cls in [target] + target.__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
@@ -189,19 +189,19 @@ class _DispatchDescriptor(object):
 
 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."""
@@ -209,7 +209,7 @@ class _ListenerCollection(object):
         if not self._exec_once:
             self(*args, **kw)
             self._exec_once = True
-    
+
     def __call__(self, *args, **kw):
         """Execute this event."""
 
@@ -217,7 +217,7 @@ class _ListenerCollection(object):
             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.
@@ -227,23 +227,23 @@ class _ListenerCollection(object):
     # 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)
@@ -258,27 +258,27 @@ class _ListenerCollection(object):
             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
index 7b77831df3e131b84a0a57c086544adde45ed4f1..c1f10977d8243213f38c6b409810104ff489a13c 100644 (file)
@@ -11,55 +11,55 @@ from sqlalchemy import event, exc
 class DDLEvents(event.Events):
     """
     Define create/drop event listers for schema objects.
-    
+
     These events currently apply to :class:`.Table`
     and :class:`.MetaData` objects as targets.
-    
+
     e.g.::
-    
+
         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
@@ -69,12 +69,12 @@ class DDLEvents(event.Events):
          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
@@ -84,12 +84,12 @@ class DDLEvents(event.Events):
          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
@@ -99,12 +99,12 @@ class DDLEvents(event.Events):
          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
@@ -114,24 +114,24 @@ class DDLEvents(event.Events):
          argument in the case of a :class:`.MetaData` object,
          which is the list of :class:`.Table` objects for which
          DROP has been emitted.
-           
+
         """
-    
+
 
 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,
@@ -139,19 +139,19 @@ class PoolEvents(event.Events):
     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
@@ -161,7 +161,7 @@ class PoolEvents(event.Events):
             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()``.
 
@@ -222,30 +222,30 @@ class PoolEvents(event.Events):
 
 class EngineEvents(event.Events):
     """Available events for :class:`.Engine`.
-    
+
     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):
         from sqlalchemy.engine.base import Connection, \
@@ -254,7 +254,7 @@ class EngineEvents(event.Events):
             target.Connection = _listener_connection_cls(
                                         Connection, 
                                         target.dispatch)
-        
+
         if not retval:
             if identifier == 'before_execute':
                 orig_fn = fn
@@ -270,7 +270,7 @@ class EngineEvents(event.Events):
                         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 "
@@ -284,7 +284,7 @@ class EngineEvents(event.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."""
@@ -295,31 +295,31 @@ class EngineEvents(event.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."""
 
index 1eb5bf91600400c3501a4cec6f8a983d0e50d0e1..b50e000a2e6e77b3fb63390c6be7e71df5c7c8f2 100644 (file)
@@ -68,13 +68,13 @@ class InvalidRequestError(SQLAlchemyError):
 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."""
 
index bc62c6efaf860f6ca5d11e4c16fa0165fb0c6b5d..969f60326a53922bb2181af2183a64431ffdc685 100644 (file)
@@ -179,7 +179,7 @@ class AssociationProxy(object):
             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)
@@ -233,7 +233,7 @@ class AssociationProxy(object):
             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:
@@ -254,7 +254,7 @@ class AssociationProxy(object):
             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
@@ -279,7 +279,7 @@ class AssociationProxy(object):
 
     def any(self, criterion=None, **kwargs):
         return self._comparator.any(getattr(self.target_class, self.value_attr).has(criterion, **kwargs))
-    
+
     def has(self, criterion=None, **kwargs):
         return self._comparator.has(getattr(self.target_class, self.value_attr).has(criterion, **kwargs))
 
@@ -308,15 +308,15 @@ class _lazy_collection(object):
 
     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.  
-        
+        """Constructs an _AssociationCollection.
+
         This will always be a subclass of either _AssociationList,
         _AssociationSet, or _AssociationDict.
 
@@ -360,7 +360,7 @@ class _AssociationCollection(object):
         self.parent = state['parent']
         self.lazy_collection = state['lazy_collection']
         self.parent._inflate(self)
-    
+
 class _AssociationList(_AssociationCollection):
     """Generic, converting, list-to-list proxy."""
 
index e6a6ca744eb369d47baa375e7c384c8102edc4d3..0b96ce25dd84977dc0ef4de3f926fcad778a8677 100644 (file)
@@ -14,24 +14,24 @@ 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]
@@ -71,7 +71,7 @@ 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
@@ -86,7 +86,7 @@ method which can be used for compilation of embedded attributes::
 
     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)"
@@ -139,7 +139,7 @@ Changing Compilation of Types
             return "VARCHAR('max')"
         else:
             return compiler.visit_VARCHAR(element, **kw)
-    
+
     foo = Table('foo', metadata,
         Column('data', VARCHAR('max'))
     )
@@ -158,12 +158,12 @@ A big part of using the compiler extension is subclassing SQLAlchemy expression
   "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()
  
@@ -173,7 +173,7 @@ A big part of using the compiler extension is subclassing SQLAlchemy expression
   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):
@@ -209,14 +209,14 @@ def compiles(class_, *specs):
         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
@@ -225,15 +225,15 @@ def compiles(class_, *specs):
             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)
-        
+
index 1199e69f37b5f42ae43bf38a087e773e2d50550a..feee435ed1b7b03fe5b531289084b7a94dc5aa85 100755 (executable)
@@ -39,7 +39,7 @@ The resulting table and mapper are accessible via
 
     # access the mapped Table
     SomeClass.__table__
-    
+
     # access the Mapper
     SomeClass.__mapper__
 
@@ -57,7 +57,7 @@ just give the column a name.  Below, column "some_table_id" is mapped to the
     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::
@@ -66,7 +66,7 @@ added to the underlying :class:`.Table` and
     SomeClass.related = relationship(RelatedInfo)
 
 Classes which are constructed using declarative can interact freely
-with classes that are mapped explicitly with :func:`mapper`.   
+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,
@@ -179,7 +179,7 @@ the :class:`.MetaData` object used by the declarative base::
         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)
@@ -211,11 +211,11 @@ using Python 2.6 style properties::
         @property
         def attr(self):
             return self._attr
-        
+
         @attr.setter
         def attr(self, attr):
             self._attr = attr
-            
+
         attr = synonym('_attr', descriptor=attr)
 
 The above synonym is then usable as an instance attribute as well as a
@@ -230,7 +230,7 @@ conjunction with ``@property``::
 
     class MyClass(Base):
         __tablename__ = 'sometable'
-    
+
         id = Column(Integer, primary_key=True)
         _attr = Column('attr', String)
 
@@ -277,19 +277,19 @@ 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)
@@ -357,15 +357,15 @@ to a table::
 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']
 
@@ -386,13 +386,13 @@ 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()
@@ -488,7 +488,7 @@ Concrete is defined as a subclass which has its own table and sets the
         __tablename__ = 'people'
         id = Column(Integer, primary_key=True)
         name = Column(String(50))
-        
+
     class Engineer(Person):
         __tablename__ = 'engineers'
         __mapper_args__ = {'concrete':True}
@@ -509,16 +509,16 @@ requires usage of :func:`~sqlalchemy.orm.util.polymorphic_union`::
                     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}
@@ -526,7 +526,7 @@ requires usage of :func:`~sqlalchemy.orm.util.polymorphic_union`::
     class Manager(Person):
         __table__ = managers
         __mapper_args__ = {'polymorphic_identity':'manager', 'concrete':True}
-    
+
 
 Mixin Classes
 ==============
@@ -541,10 +541,10 @@ 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)
 
 
@@ -600,16 +600,16 @@ 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
@@ -631,7 +631,7 @@ will resolve them at class construction time::
     class MyModel(Base,MyMixin):
         __tablename__='test'
         id =  Column(Integer, primary_key=True)
-    
+
 Mixing in Relationships
 ~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -647,26 +647,26 @@ reference a common target class via many-to-one::
         @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.  
+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::
 
@@ -674,7 +674,7 @@ to get it's name::
         @declared_attr
         def target_id(cls):
             return Column('target_id', ForeignKey('target.id'))
-        
+
         @declared_attr
         def target(cls):
             return relationship("Target",
@@ -810,7 +810,7 @@ from multiple collections::
     from sqlalchemy.ext.declarative import declared_attr
 
     class MySQLSettings:
-        __table_args__ = {'mysql_engine':'InnoDB'}             
+        __table_args__ = {'mysql_engine':'InnoDB'}
 
     class MyOtherMixin:
         __table_args__ = {'info':'foo'}
@@ -892,7 +892,7 @@ correctly combines the actions of the other metaclasses. For example::
             # This is needed to successfully combine
             # two mixins which both have metaclasses
             pass
-        
+
         class MyModel(Base,MyMixin1,MyMixin2):
             __tablename__ = 'awooooga'
             __metaclass__ = CombinedMeta
@@ -901,7 +901,7 @@ correctly combines the actions of the other metaclasses. For example::
 For this reason, if a mixin requires a custom metaclass, this should
 be mentioned in any documentation of that mixin to avoid confusion
 later down the line.
-            
+
 Class Constructor
 =================
 
@@ -917,7 +917,7 @@ 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::  
+setup using :func:`~sqlalchemy.orm.scoped_session` might look like::
 
     engine = create_engine('postgresql://scott:tiger@localhost/test')
     Session = scoped_session(sessionmaker(autocommit=False,
@@ -947,7 +947,7 @@ 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 exceptions.InvalidRequestError(
@@ -973,19 +973,19 @@ def _as_declarative(cls, classname, 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 (
@@ -1015,7 +1015,7 @@ def _as_declarative(cls, classname, dict_):
                 continue
             elif base is not cls:
                 # we're a mixin.
-                
+
                 if isinstance(obj, Column):
                     if obj.foreign_keys:
                         raise exceptions.InvalidRequestError(
@@ -1048,7 +1048,7 @@ def _as_declarative(cls, classname, dict_):
     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
 
@@ -1056,7 +1056,7 @@ def _as_declarative(cls, classname, dict_):
     # than the original columns from any mixins
     for k, v in mapper_args.iteritems():
         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"
@@ -1071,7 +1071,7 @@ def _as_declarative(cls, classname, 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 "
@@ -1108,7 +1108,7 @@ def _as_declarative(cls, classname, dict_):
     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):
@@ -1139,7 +1139,7 @@ def _as_declarative(cls, classname, dict_):
                         "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):
@@ -1180,7 +1180,7 @@ def _as_declarative(cls, classname, dict_):
                     "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:
@@ -1195,7 +1195,7 @@ def _as_declarative(cls, classname, dict_):
                         (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
@@ -1203,19 +1203,19 @@ def _as_declarative(cls, classname, dict_):
         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.   
+        # 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
@@ -1227,7 +1227,7 @@ def _as_declarative(cls, classname, dict_):
                     # 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, 
@@ -1267,7 +1267,7 @@ class DeclarativeMeta(type):
 class _GetColumns(object):
     def __init__(self, cls):
         self.cls = cls
-        
+
     def __getattr__(self, key):
         mapper = class_mapper(self.cls, compile=False)
         if mapper:
@@ -1275,7 +1275,7 @@ class _GetColumns(object):
                 raise exceptions.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 exceptions.InvalidRequestError(
@@ -1288,16 +1288,16 @@ 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])
@@ -1312,7 +1312,7 @@ def _deferred_relationship(cls, prop):
         def return_cls():
             try:
                 x = eval(arg, globals(), d)
-                
+
                 if isinstance(x, _GetColumns):
                     return x.cls
                 else:
@@ -1395,7 +1395,7 @@ class declared_attr(property):
     .. 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 
@@ -1403,29 +1403,29 @@ class declared_attr(property):
     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':
@@ -1435,13 +1435,13 @@ class declared_attr(property):
                     }
                 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)
 
index 880dfb743d992575e7b44d776ae31e73d46ba134..41fae8e7bcb1d9ae2de24b24159e4fa7d41b0826 100644 (file)
@@ -40,10 +40,10 @@ class ShardedSession(Session):
         :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.   
-          
+          objects.
+
         """
         super(ShardedSession, self).__init__(**kwargs)
         self.shard_chooser = shard_chooser
@@ -55,7 +55,7 @@ class ShardedSession(Session):
         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)
@@ -66,7 +66,7 @@ class ShardedSession(Session):
             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)
@@ -81,18 +81,18 @@ class ShardedQuery(Query):
         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):
         if self._shard_id is not None:
             result = self.session.connection(
@@ -106,7 +106,7 @@ class ShardedQuery(Query):
                             mapper=self._mapper_zero(),
                             shard_id=shard_id).execute(context.statement, self._params)
                 partial = partial + list(self.instances(result, context))
-                
+
             # if some kind of in memory 'sorting' 
             # were done, this is where it would happen
             return iter(partial)
@@ -122,4 +122,4 @@ class ShardedQuery(Query):
                     return o
             else:
                 return None
-    
+
index 153eccce2ddf6f759f1780789f1ffafeff9de45a..f3989a84d41ddf1abc2dbcceb0ae98efa5a05dfd 100644 (file)
@@ -13,7 +13,7 @@ Consider a table `interval` as below::
 
     from sqlalchemy import MetaData, Table, Column, Integer
     from sqlalchemy.orm import mapper, create_session
-    
+
     engine = create_engine('sqlite://')
     metadata = MetaData()
 
@@ -22,22 +22,22 @@ Consider a table `interval` as below::
         Column('start', Integer, nullable=False),
         Column('end', Integer, nullable=False))
     metadata.create_all(engine)
-    
+
 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::
-    
+
     # A base class for intervals
 
     from sqlalchemy.orm import hybrid
-    
+
     class Interval(object):
         def __init__(self, start, end):
             self.start = start
             self.end = end
-        
+
         @hybrid.property
         def length(self):
             return self.end - self.start
@@ -45,13 +45,13 @@ or as the class itself::
         @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)
 
 
-        
+
 """
 from sqlalchemy import util
 from sqlalchemy.orm import attributes, interfaces
@@ -60,7 +60,7 @@ class method(object):
     def __init__(self, func, expr=None):
         self.func = func
         self.expr = expr or func
-        
+
     def __get__(self, instance, owner):
         if instance is None:
             return new.instancemethod(self.expr, owner, owner.__class__)
@@ -84,13 +84,13 @@ class property_(object):
             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):
         self.fset = fset
         return self
@@ -98,11 +98,11 @@ class property_(object):
     def deleter(self, fdel):
         self.fdel = fdel
         return self
-    
+
     def expression(self, expr):
         self.expr = expr
         return self
-    
+
     def comparator(self, comparator):
         proxy_attr = attributes.\
                         create_proxied_attribute(self)
@@ -115,15 +115,15 @@ class property_(object):
 class Comparator(interfaces.PropComparator):
     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
-        
+
 
index 2bb8793229a5d8d6a56157396290aeb0e921f247..11a7977f67e5c9a78a5e663d2177fa13b164a87c 100644 (file)
@@ -22,47 +22,47 @@ import weakref
 class Mutable(object):
     """Mixin that defines transparent propagation of change
     events to a parent object.
-    
+
     """
-    
+
     @memoized_property
     def _parents(self):
         """Dictionary of parent object->attribute name on the parent."""
-        
+
         return weakref.WeakKeyDictionary()
-        
+
     def change(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' accepts objects of type %s" % (key, cls))
-        
-        
+
+
     @classmethod
     def associate_with_attribute(cls, attribute):
         """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.   
-            
+            """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:
@@ -73,20 +73,20 @@ class Mutable(object):
         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) 
             value._parents[target.obj()] = key
             if isinstance(oldvalue, cls):
                 oldvalue._parents.pop(state.obj(), None)
             return value
-        
+
         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)
@@ -97,7 +97,7 @@ class Mutable(object):
     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*
@@ -105,7 +105,7 @@ class Mutable(object):
            :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_):
@@ -114,39 +114,39 @@ class Mutable(object):
                     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 occurences of a 
         particular type, use the :meth:`.Mutable.associate_with` classmethod
         of the particular :meth:`.Mutable` subclass to establish a global
         assoiation.
-    
+
         .. 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)
 
@@ -156,9 +156,9 @@ class Mutable(object):
                     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
 
 
@@ -171,14 +171,14 @@ class MutableComposite(object):
     """Mixin that defines transparent propagation of change
     events on a SQLAlchemy "composite" object to its
     owning parent or parents.
-    
+
     Composite classes, in addition to meeting the usage contract
     defined in :ref:`mapper_composite`, also define some system
     of relaying change events to the given :meth:`.change` 
     method, which will notify all parents of the change.  Below
     the special Python method ``__setattr__`` is used to intercept
     all changes::
-    
+
         class Point(MutableComposite):
             def __init__(self, x, y):
                 self.x = x
@@ -187,10 +187,10 @@ class MutableComposite(object):
             def __setattr__(self, key, value):
                 object.__setattr__(self, key, value)
                 self.change()
-        
+
             def __composite_values__(self):
                 return self.x, self.y
-            
+
             def __eq__(self, other):
                 return isinstance(other, Point) and \
                     other.x == self.x and \
@@ -206,44 +206,44 @@ class MutableComposite(object):
        :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
 
     @memoized_property
     def _parents(self):
         """Dictionary of parent object->attribute name on the parent."""
-        
+
         return weakref.WeakKeyDictionary()
 
     def change(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 _listen_on_attribute(cls, attribute):
         """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.   
-            
+            """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:
                 val._parents[state.obj()] = key
@@ -251,37 +251,37 @@ class MutableComposite(object):
         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.
-            
+
             """
-            
+
             value._parents[target.obj()] = key
             if isinstance(oldvalue, cls):
                 oldvalue._parents.pop(state.obj(), None)
             return value
-        
+
         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)
 
         # TODO: need a deserialize hook here
-    
+
     @classmethod
     def _setup_listeners(cls):
         """Associate this wrapper with all future mapped compoistes
         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))
-                    
+
         event.listen(mapper, 'mapper_configured', listen_for_type)
 
index 062172bcc13d7c2d55be9fef3adb6f5dd2030187..ce63b88eaedfafb9e14c45f1e1f6b66bf791f012 100644 (file)
@@ -52,7 +52,7 @@ 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'),
@@ -71,7 +71,7 @@ related bullets for you.
 
 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.  
+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 
@@ -89,7 +89,7 @@ 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.  
+index to any value you require.
 
 
 
@@ -292,7 +292,7 @@ class OrderingList(list):
             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:
@@ -312,7 +312,7 @@ class OrderingList(list):
         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)):
index 8c098c3dff732e85c3969d8f1349791b865d9feb..077a0fd9ee39e0dc81d09a7a8e6ec433a8e4454d 100644 (file)
@@ -18,17 +18,17 @@ 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 
@@ -81,7 +81,7 @@ __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):
@@ -101,15 +101,15 @@ def Serializer(*args, **kw):
         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
@@ -119,7 +119,7 @@ def Deserializer(file, metadata=None, scoped_session=None, engine=None):
             return metadata.bind
         else:
             return None
-            
+
     def persistent_load(id):
         m = our_ids.match(id)
         if not m:
@@ -152,10 +152,10 @@ def dumps(obj, protocol=0):
     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()
-    
-    
+
+
index ebe2feb7fe6f4a83e2cf28d8cd0d780ce29cc748..9e6f63acac8673434aa505ab51933fcd1f94b31b 100644 (file)
@@ -257,7 +257,7 @@ 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
@@ -460,7 +460,7 @@ def _class_for_table(session, engine, selectable, base_cls, mapper_kwargs):
         engine_encoding = engine.dialect.encoding 
         mapname = mapname.encode(engine_encoding)
     # end Py2K
-    
+
     if isinstance(selectable, Table):
         klass = TableClassType(mapname, (base_cls,), {})
     else:
@@ -475,10 +475,10 @@ def _class_for_table(session, engine, selectable, base_cls, mapper_kwargs):
         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
@@ -486,12 +486,12 @@ def _class_for_table(session, engine, selectable, base_cls, mapper_kwargs):
     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
@@ -500,16 +500,16 @@ def _class_for_table(session, engine, selectable, base_cls, mapper_kwargs):
                    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`.
 
@@ -525,10 +525,10 @@ class SqlSoup(object):
           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)):
@@ -536,10 +536,10 @@ class SqlSoup(object):
         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`."""
@@ -551,83 +551,83 @@ class SqlSoup(object):
         """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.frozendict()):
         """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.
@@ -648,8 +648,8 @@ class SqlSoup(object):
           argument.
         :param schema: String schema name to use if the
           ``tablename`` argument is present.
-          
-          
+
+
         """
         if attrname in self._cache:
             raise InvalidRequestError(
@@ -657,7 +657,7 @@ class SqlSoup(object):
                 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."
@@ -692,7 +692,7 @@ class SqlSoup(object):
                 raise PKNotFoundError(
                             "selectable '%s' does not have a primary "
                             "key defined" % selectable)
-                
+
         mapped_cls = _class_for_table(
             self.session,
             self.engine,
@@ -702,14 +702,14 @@ class SqlSoup(object):
         )
         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"
@@ -718,7 +718,7 @@ class SqlSoup(object):
           ``object``.
         :param mapper_args: Dictionary of arguments which will
           be passed directly to :func:`.orm.mapper`.
-        
+
         """
 
         return _class_for_table(
@@ -735,7 +735,7 @@ class SqlSoup(object):
 
         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"
@@ -744,9 +744,9 @@ class SqlSoup(object):
           ``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).
@@ -759,7 +759,7 @@ class SqlSoup(object):
 
         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..
@@ -771,24 +771,24 @@ class SqlSoup(object):
           ``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)
 
index 3acdcd1025a5dce0ba6f22e7f4c92c7657e6e6ff..0a1eec75d032c062407b50f9450c7ab09caa6866 100644 (file)
@@ -19,23 +19,23 @@ class PoolListener(object):
 
     .. 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
@@ -66,14 +66,14 @@ class PoolListener(object):
     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',
@@ -86,8 +86,8 @@ class PoolListener(object):
             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()``.
 
@@ -151,16 +151,16 @@ class ConnectionProxy(object):
 
     .. note:: :class:`ConnectionProxy` is deprecated.   Please
        refer to :class:`.EngineEvents`.
-    
+
     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)
@@ -168,14 +168,14 @@ class ConnectionProxy(object):
     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):
 
@@ -240,66 +240,66 @@ class ConnectionProxy(object):
                      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)
-        
+
index e749ec031a6d5726422676c942e8d0808f0baeb7..adfede75f20f676066b266027e8144cfdd14850a 100644 (file)
@@ -45,29 +45,29 @@ def class_logger(cls, enable=False):
     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
@@ -86,7 +86,7 @@ class InstanceLogger(object):
     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 \
@@ -98,17 +98,17 @@ class InstanceLogger(object):
     #
     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
@@ -121,27 +121,27 @@ class InstanceLogger(object):
 
     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
 
@@ -154,14 +154,14 @@ class InstanceLogger(object):
 
     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()
@@ -176,9 +176,9 @@ def instance_logger(instance, echoflag=None):
     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
@@ -188,9 +188,9 @@ def instance_logger(instance, echoflag=None):
         # 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.
index e9f4f14f6ff8846f4e348364bf53d92ef9496646..0b77b0239d8f8cd8135262865bb0165a9d0c9e97 100644 (file)
@@ -143,7 +143,7 @@ def scoped_session(session_factory, scopefunc=None):
 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.
@@ -178,10 +178,10 @@ def create_session(bind=None, **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`.
 
@@ -212,7 +212,7 @@ def relationship(argument, secondary=None, **kwargs):
       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
@@ -220,7 +220,7 @@ def relationship(argument, secondary=None, **kwargs):
       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, 
@@ -263,7 +263,7 @@ def relationship(argument, secondary=None, **kwargs):
 
       * ``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
@@ -273,9 +273,9 @@ def relationship(argument, secondary=None, **kwargs):
       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.
@@ -288,11 +288,11 @@ def relationship(argument, secondary=None, **kwargs):
 
     :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.  
+      the resulting descriptor placed on the class.
       **Deprecated.**  Please see :class:`.AttributeEvents`.
 
     :param foreign_keys:
@@ -307,7 +307,7 @@ def relationship(argument, secondary=None, **kwargs):
       "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
@@ -325,7 +325,7 @@ def relationship(argument, secondary=None, **kwargs):
       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 
@@ -343,7 +343,7 @@ def relationship(argument, secondary=None, **kwargs):
       * ``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)
@@ -352,7 +352,7 @@ def relationship(argument, secondary=None, **kwargs):
         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
@@ -370,18 +370,18 @@ def relationship(argument, secondary=None, **kwargs):
         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
@@ -389,21 +389,21 @@ def relationship(argument, secondary=None, **kwargs):
       "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.
@@ -456,7 +456,7 @@ def relationship(argument, secondary=None, **kwargs):
       (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.
 
@@ -503,7 +503,7 @@ def relationship(argument, secondary=None, **kwargs):
       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
@@ -528,9 +528,9 @@ def relationship(argument, secondary=None, **kwargs):
 
 def relation(*arg, **kw):
     """A synonym for :func:`relationship`."""
-    
+
     return relationship(*arg, **kw)
-    
+
 def dynamic_loader(argument, secondary=None, primaryjoin=None,
                    secondaryjoin=None, foreign_keys=None, backref=None,
                    post_update=False, cascade=False, remote_side=None,
@@ -614,11 +614,11 @@ def column_property(*args, **kwargs):
           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`
@@ -634,10 +634,10 @@ def column_property(*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.
 
@@ -788,7 +788,7 @@ def mapper(class_, local_table=None, *args, **params):
         :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.
@@ -797,20 +797,20 @@ def mapper(class_, local_table=None, *args, **params):
            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.
 
@@ -939,7 +939,7 @@ def comparable_property(comparator_factory, descriptor=None):
       from sqlalchemy.orm import mapper, comparable_property
       from sqlalchemy.orm.interfaces import PropComparator
       from sqlalchemy.sql import func
-      
+
       class MyClass(object):
           @property
           def myprop(self):
@@ -954,12 +954,12 @@ def comparable_property(comparator_factory, descriptor=None):
 
     Used with the ``properties`` dictionary sent to
     :func:`~sqlalchemy.orm.mapper`.
-    
+
     Note that :func:`comparable_property` is usually not needed for basic
     needs. The recipe at :mod:`.derived_attributes` offers a simpler
     pure-Python method of achieving a similar result using class-bound
     attributes with SQLAlchemy expression constructs.
-    
+
     :param comparator_factory:
       A PropComparator subclass or factory that defines operator behavior
       for this property.
@@ -973,21 +973,21 @@ def comparable_property(comparator_factory, descriptor=None):
 
     """
     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
@@ -999,7 +999,7 @@ def clear_mappers():
     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:
@@ -1025,10 +1025,10 @@ def joinedload(*keys, **kw):
     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.
@@ -1039,17 +1039,17 @@ def joinedload(*keys, **kw):
 
     :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:
@@ -1080,7 +1080,7 @@ def joinedload_all(*keys, **kw):
     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
@@ -1102,11 +1102,11 @@ def joinedload_all(*keys, **kw):
 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 
@@ -1115,10 +1115,10 @@ def subqueryload(*keys):
     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.
@@ -1128,7 +1128,7 @@ def subqueryload(*keys):
         query(Order).options(subqueryload_all(Order.items, Item.keywords))
 
     See also:  :func:`joinedload`, :func:`lazyload`
-    
+
     """
     return strategies.EagerLazyOption(keys, lazy="subquery")
 
@@ -1147,7 +1147,7 @@ def subqueryload_all(*keys):
     load in one subquery eager load.
 
     Individual descriptors are accepted as arguments as well::
-    
+
         query.options(subqueryload_all(User.orders, Order.items,
         Item.keywords))
 
@@ -1155,7 +1155,7 @@ def subqueryload_all(*keys):
 
     """
     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.
@@ -1193,16 +1193,16 @@ def noload(*keys):
 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.
@@ -1222,11 +1222,11 @@ def contains_eager(*keys, **kwargs):
 
     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.
@@ -1235,7 +1235,7 @@ def contains_eager(*keys, **kwargs):
     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)).\\
index 56cae6a18457bd211f06095c93f5fd68970f1a18..6b57d33f5f5f0c1256151a9b99c34c8682c7b45f 100644 (file)
@@ -53,7 +53,7 @@ PASSIVE_OFF = False #util.symbol('PASSIVE_OFF')
 
 class QueryableAttribute(interfaces.PropComparator):
     """Base class for class-bound attributes. """
-    
+
     def __init__(self, class_, key, impl=None, 
                         comparator=None, parententity=None):
         self.class_ = class_
@@ -73,15 +73,15 @@ class QueryableAttribute(interfaces.PropComparator):
 
     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, **kwargs):
         return self.impl.get_history(instance_state(instance),
                                         instance_dict(instance), **kwargs)
-    
+
     def __selectable__(self):
         # TODO: conditionally attach this method based on clause_element ?
         return self
@@ -100,7 +100,7 @@ class QueryableAttribute(interfaces.PropComparator):
 
     def hasparent(self, state, optimistic=False):
         return self.impl.hasparent(state, optimistic=optimistic)
-    
+
     def __getattr__(self, key):
         try:
             return getattr(self.comparator, key)
@@ -111,7 +111,7 @@ class QueryableAttribute(interfaces.PropComparator):
                     type(self.comparator).__name__, 
                     key)
             )
-        
+
     def __str__(self):
         return repr(self.parententity) + "." + self.property.key
 
@@ -146,15 +146,15 @@ def create_proxied_attribute(descriptor):
     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, 
@@ -165,7 +165,7 @@ def create_proxied_attribute(descriptor):
             self._comparator = comparator
             self.adapter = adapter
             self.__doc__ = doc
-            
+
         @util.memoized_property
         def comparator(self):
             if util.callable(self._comparator):
@@ -173,20 +173,20 @@ def create_proxied_attribute(descriptor):
             if self.adapter:
                 self._comparator = self._comparator.adapted(self.adapter)
             return self._comparator
-        
+
         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:
@@ -219,7 +219,7 @@ class AttributeImpl(object):
 
         \class_
           associated class
-          
+
         key
           string name of the attribute
 
@@ -251,12 +251,12 @@ class AttributeImpl(object):
           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
@@ -268,30 +268,30 @@ class AttributeImpl(object):
             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.
@@ -337,17 +337,17 @@ class AttributeImpl(object):
 
     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, 
@@ -355,7 +355,7 @@ class AttributeImpl(object):
 
         """
         raise NotImplementedError()
-        
+
     def initialize(self, state, dict_):
         """Initialize the given state's attribute with an empty value."""
 
@@ -379,7 +379,7 @@ class AttributeImpl(object):
                 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)
@@ -404,7 +404,7 @@ class AttributeImpl(object):
 
             # 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)
 
@@ -515,7 +515,7 @@ class MutableScalarAttributeImpl(ScalarAttributeImpl):
             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_):
@@ -545,7 +545,7 @@ class ScalarObjectAttributeImpl(ScalarAttributeImpl):
        where the target object is also instrumented.
 
        Adds events to delete/set operations.
-       
+
     """
 
     accepts_scalar_loader = False
@@ -585,12 +585,12 @@ class ScalarObjectAttributeImpl(ScalarAttributeImpl):
                 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:
@@ -611,14 +611,14 @@ class ScalarObjectAttributeImpl(ScalarAttributeImpl):
             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)
 
@@ -630,7 +630,7 @@ class ScalarObjectAttributeImpl(ScalarAttributeImpl):
                 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)
 
@@ -691,24 +691,24 @@ class CollectionAttributeImpl(AttributeImpl):
 
         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)
@@ -844,7 +844,7 @@ class CollectionAttributeImpl(AttributeImpl):
         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)
@@ -893,7 +893,7 @@ def backref_listeners(attribute, key, uselist):
                             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)
@@ -926,19 +926,19 @@ def backref_listeners(attribute, key, uselist):
                                             state.obj(), 
                                             initiator,
                                             passive=PASSIVE_NO_FETCH)
-    
+
     if uselist:
         event.listen(attribute, "append", append, retval=True, raw=True)
     else:
         event.listen(attribute, "set", set_, retval=True, raw=True)
     # TODO: need coverage in test/orm/ of remove event
     event.listen(attribute, "remove", remove, retval=True, raw=True)
-        
+
 class History(tuple):
     """A 3-tuple of added, unchanged and deleted values,
     representing the changes which have occured on an instrumented
     attribute.
-    
+
     Each tuple member is an iterable sequence.
 
     """
@@ -948,57 +948,57 @@ class History(tuple):
     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 c is not PASSIVE_NO_RESULT)
@@ -1039,7 +1039,7 @@ class History(tuple):
     @classmethod
     def from_object_attribute(cls, attribute, state, current):
         original = state.committed_state.get(attribute.key, NEVER_SET)
-        
+
         if current is NO_VALUE:
             if (original is not None and
                 original is not NEVER_SET and
@@ -1064,7 +1064,7 @@ class History(tuple):
     def from_collection(cls, attribute, state, current):
         original = state.committed_state.get(attribute.key, NEVER_SET)
         current = getattr(current, '_sa_adapter')
-        
+
         if original is NO_VALUE:
             return cls(list(current), (), ())
         elif original is NEVER_SET:
@@ -1072,10 +1072,10 @@ class History(tuple):
         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],
@@ -1087,25 +1087,25 @@ HISTORY_BLANK = History(None, None, None)
 def get_history(obj, key, **kwargs):
     """Return a :class:`.History` record for the given object 
     and attribute key.
-    
+
     :param obj: an object whose class is instrumented by the
-      attributes package.  
-    
+      attributes package.
+
     :param key: string attribute name.
-    
+
     :param kwargs: Optional keyword arguments currently
       include the ``passive`` flag, which 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`.
-    
+
     """
     return get_state_history(instance_state(obj), key, **kwargs)
 
 def get_state_history(state, key, **kwargs):
     return state.get_history(key, **kwargs)
 
-    
+
 def has_parent(cls, obj, key, optimistic=False):
     """TODO"""
     manager = manager_of_class(cls)
@@ -1120,12 +1120,12 @@ def register_attribute(class_, key, **kw):
                             comparator, parententity, doc=doc)
     register_attribute_impl(class_, key, **kw)
     return desc
-    
-def register_attribute_impl(class_, key,         
+
+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)
@@ -1135,7 +1135,7 @@ def register_attribute_impl(class_, key,
         typecallable = kw.pop('typecallable', None)
 
     dispatch = manager[key].dispatch
-    
+
     if impl_class:
         impl = impl_class(class_, key, typecallable, dispatch, **kw)
     elif uselist:
@@ -1151,22 +1151,22 @@ def register_attribute_impl(class_, key,
         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
 
@@ -1175,36 +1175,36 @@ def unregister_attribute(class_, 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.
@@ -1215,20 +1215,20 @@ def set_committed_value(instance, key, value):
     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)
@@ -1241,7 +1241,7 @@ def get_attribute(instance, key):
     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_)
@@ -1254,20 +1254,19 @@ def del_attribute(instance, key):
     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)
-    
-    
\ No newline at end of file
+
index b0fab36c0de8264a839b42f34d2dc2b508bb503d..4b03a50db4f9d5758389f83b13ae82b6380da7d5 100644 (file)
@@ -449,7 +449,7 @@ class collection(object):
 # implementations
 def collection_adapter(collection):
     """Fetch the :class:`.CollectionAdapter` for a collection."""
-    
+
     return getattr(collection, '_sa_adapter', None)
 
 def collection_iter(collection):
@@ -479,14 +479,14 @@ class CollectionAdapter(object):
 
     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."
@@ -495,7 +495,7 @@ class CollectionAdapter(object):
     @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)
@@ -555,7 +555,7 @@ class CollectionAdapter(object):
 
     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):
@@ -578,7 +578,7 @@ class CollectionAdapter(object):
 
     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)
@@ -592,7 +592,7 @@ class CollectionAdapter(object):
 
     def __iter__(self):
         """Iterate over entities in the collection."""
-        
+
         # Py3K requires iter() here
         return iter(getattr(self._data(), '_sa_iterator')())
 
@@ -926,7 +926,7 @@ def __set(collection, item, _sa_initiator=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:
@@ -987,12 +987,12 @@ def _list_decorators():
                 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:
@@ -1041,7 +1041,7 @@ def _list_decorators():
         _tidy(__delslice__)
         return __delslice__
     # end Py2K
-    
+
     def extend(fn):
         def extend(self, iterable):
             for value in iterable:
@@ -1371,7 +1371,7 @@ class InstrumentedDict(dict):
     __instrumentation__ = {
         'iterator': 'itervalues', }
     # end Py2K
-    
+
 __canned_instrumentation = {
     list: InstrumentedList,
     set: InstrumentedSet,
index 57c6d6e9e53431ff2cdbab47844e1545035f8ffe..8acf77ad8d7fbafed2a6a2f65b683b78a7cae6e8 100644 (file)
@@ -33,29 +33,29 @@ class DependencyProcessor(object):
                     "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 aggreagte.
-        
+
         """
         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)
@@ -77,7 +77,7 @@ class DependencyProcessor(object):
                                         uow, 
                                         self.mapper.primary_base_mapper
                                         )
-        
+
         self.per_property_dependencies(uow, 
                                         parent_saves, 
                                         child_saves, 
@@ -86,15 +86,15 @@ class DependencyProcessor(object):
                                         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
@@ -104,7 +104,7 @@ class DependencyProcessor(object):
 
         # locate and disable the aggregate processors
         # for this dependency
-        
+
         if isdelete:
             before_delete = unitofwork.ProcessAll(uow, self, True, True)
             before_delete.disabled = True
@@ -113,14 +113,14 @@ class DependencyProcessor(object):
             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 = [
@@ -129,7 +129,7 @@ class DependencyProcessor(object):
             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(
@@ -145,14 +145,14 @@ class DependencyProcessor(object):
             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
 
@@ -171,7 +171,7 @@ class DependencyProcessor(object):
                                                 uow, 
                                                 state, 
                                                 parent_base_mapper)
-                
+
             if child_in_cycles:
                 child_actions = []
                 for child_state, child in sum_:
@@ -192,7 +192,7 @@ class DependencyProcessor(object):
                                                         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:
@@ -201,23 +201,23 @@ class DependencyProcessor(object):
                                                 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):
         passive = not isdelete or self.passive_deletes
-        
+
         for s in states:
             # TODO: add a high speed method 
             # to InstanceState which returns:  attribute
@@ -230,7 +230,7 @@ class DependencyProcessor(object):
                 return True
         else:
             return False
-        
+
     def _verify_canload(self, state):
         if state is not None and \
             not self.mapper._canload(state, 
@@ -249,7 +249,7 @@ class DependencyProcessor(object):
                 "Attempting to flush an item of type %s on collection '%s', "
                 "whose mapper does not inherit from that of %s." % 
                 (state.class_, self.prop, self.mapper.class_))
-            
+
     def _synchronize(self, state, child, associationrow,
                                             clearkeys, uowcommit):
         raise NotImplementedError()
@@ -275,7 +275,7 @@ class DependencyProcessor(object):
                         [r for l, r in self.prop.synchronize_pairs]
                 )
                 break
-        
+
     def _pks_changed(self, uowcommit, state):
         raise NotImplementedError()
 
@@ -283,7 +283,7 @@ class DependencyProcessor(object):
         return "%s(%s)" % (self.__class__.__name__, self.prop)
 
 class OneToManyDP(DependencyProcessor):
-    
+
     def per_property_dependencies(self, uow, parent_saves, 
                                                 child_saves, 
                                                 parent_deletes, 
@@ -300,37 +300,37 @@ class OneToManyDP(DependencyProcessor):
                                             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(
@@ -341,7 +341,7 @@ class OneToManyDP(DependencyProcessor):
                                             uow, 
                                             self.mapper.primary_base_mapper, 
                                             True)
-            
+
             # TODO: this whole block is not covered
             # by any tests
             if not isdelete:
@@ -378,7 +378,7 @@ class OneToManyDP(DependencyProcessor):
                 (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 
@@ -398,21 +398,21 @@ class OneToManyDP(DependencyProcessor):
                             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)
-            
+
             history = uowcommit.get_attribute_history(
                                             state, 
                                             self.key, 
@@ -451,14 +451,14 @@ class OneToManyDP(DependencyProcessor):
                                         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)
 
@@ -478,7 +478,7 @@ class OneToManyDP(DependencyProcessor):
                                             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):
@@ -492,12 +492,12 @@ class OneToManyDP(DependencyProcessor):
                                     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, 
@@ -520,7 +520,7 @@ class OneToManyDP(DependencyProcessor):
                     for child in history.unchanged:
                         self._synchronize(state, child, None, 
                                                 False, uowcommit, True)
-        
+
     def _synchronize(self, state, child, 
                             associationrow, clearkeys, uowcommit,
                             pks_changed):
@@ -593,7 +593,7 @@ class ManyToOneDP(DependencyProcessor):
                                     isdelete, childisdelete):
 
         if self.post_update:
-            
+
             if not isdelete:
                 parent_post_updates = unitofwork.IssuePostUpdate(
                                             uow, 
@@ -608,7 +608,7 @@ class ManyToOneDP(DependencyProcessor):
                     uow.dependencies.update([
                         (save_parent, after_save),
                         (child_action, after_save),
-                        
+
                         (after_save, parent_post_updates)
                     ])
             else:
@@ -622,7 +622,7 @@ class ManyToOneDP(DependencyProcessor):
                     (parent_pre_updates, delete_parent),
                     (parent_pre_updates, child_action)
                 ])
-                    
+
         elif not isdelete:
             if not childisdelete:
                 uow.dependencies.update([
@@ -633,7 +633,7 @@ class ManyToOneDP(DependencyProcessor):
                 uow.dependencies.update([
                     (after_save, save_parent),
                 ])
-                
+
         else:
             if childisdelete:
                 uow.dependencies.update([
@@ -661,7 +661,7 @@ class ManyToOneDP(DependencyProcessor):
                                                             '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)
@@ -676,7 +676,7 @@ class ManyToOneDP(DependencyProcessor):
                         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(
@@ -687,7 +687,7 @@ class ManyToOneDP(DependencyProcessor):
         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
@@ -710,7 +710,7 @@ class ManyToOneDP(DependencyProcessor):
                 for child in history.added:
                     self._synchronize(state, child, None, False, 
                                             uowcommit, "add")
-                
+
                 if self.post_update:
                     self._post_update(state, uowcommit, history.sum())
 
@@ -728,7 +728,7 @@ class ManyToOneDP(DependencyProcessor):
                 "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:
@@ -743,12 +743,12 @@ 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):
@@ -759,7 +759,7 @@ class DetectKeySwitch(DependencyProcessor):
                 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):
@@ -770,10 +770,10 @@ class DetectKeySwitch(DependencyProcessor):
         uow.dependencies.update([
             (parent_saves, after_save)
         ])
-        
+
     def per_state_flush_actions(self, uow, states, isdelete):
         pass
-        
+
     def presort_deletes(self, uowcommit, states):
         pass
 
@@ -787,9 +787,9 @@ class DetectKeySwitch(DependencyProcessor):
         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
 
@@ -800,13 +800,13 @@ class DetectKeySwitch(DependencyProcessor):
         # 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:
@@ -815,7 +815,7 @@ class DetectKeySwitch(DependencyProcessor):
                 else:
                     notswitched.add(s)
         return switched
-            
+
     def _process_key_switches(self, deplist, uowcommit):
         switchers = self._key_switchers(uowcommit, deplist)
         if switchers:
@@ -848,7 +848,7 @@ class DetectKeySwitch(DependencyProcessor):
 
 
 class ManyToManyDP(DependencyProcessor):
-        
+
     def per_property_dependencies(self, uow, parent_saves, 
                                                 child_saves, 
                                                 parent_deletes, 
@@ -861,14 +861,14 @@ class ManyToManyDP(DependencyProcessor):
             (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),
@@ -896,7 +896,7 @@ class ManyToManyDP(DependencyProcessor):
                 (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 
@@ -907,7 +907,7 @@ class ManyToManyDP(DependencyProcessor):
                                         state, 
                                         self.key, 
                                         passive=self.passive_deletes)
-        
+
     def presort_saves(self, uowcommit, states):
         if not self.passive_updates:
             # if no passive updates, load history on 
@@ -922,7 +922,7 @@ class ManyToManyDP(DependencyProcessor):
 
         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:
@@ -940,12 +940,12 @@ class ManyToManyDP(DependencyProcessor):
                                                     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:
@@ -969,12 +969,12 @@ class ManyToManyDP(DependencyProcessor):
                                         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)
 
@@ -1016,12 +1016,12 @@ class ManyToManyDP(DependencyProcessor):
                                         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, 
@@ -1036,17 +1036,17 @@ class ManyToManyDP(DependencyProcessor):
                                     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_(*[
@@ -1055,7 +1055,7 @@ class ManyToManyDP(DependencyProcessor):
                                 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(
@@ -1085,7 +1085,7 @@ class ManyToManyDP(DependencyProcessor):
         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:
@@ -1098,16 +1098,16 @@ class ManyToManyDP(DependencyProcessor):
                     "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, 
index 341594578b9e35dc42379a644dea297fa5daadb9..8cdde2282898982346f07672c6817e54bbcc37d3 100644 (file)
@@ -14,27 +14,27 @@ class MapperExtension(object):
     .. 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
@@ -43,13 +43,13 @@ class MapperExtension(object):
     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
@@ -75,17 +75,17 @@ class MapperExtension(object):
             '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)
-            
+
             # TODO: comparing self.methods to cls.method, 
             # this comparison is probably moot
-            
+
             if me_meth is not ls_meth:
                 if meth == 'reconstruct_instance':
                     def go(ls_meth):
@@ -109,7 +109,7 @@ class MapperExtension(object):
                             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)
@@ -121,20 +121,20 @@ class MapperExtension(object):
     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.
 
@@ -144,11 +144,11 @@ class MapperExtension(object):
     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.
 
@@ -166,10 +166,10 @@ class MapperExtension(object):
         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
 
@@ -302,7 +302,7 @@ class MapperExtension(object):
 
         The return value is only significant within the ``MapperExtension`` 
         chain; the parent mapper's behavior isn't modified by this method.
-        
+
         """
 
         return EXT_CONTINUE
@@ -319,7 +319,7 @@ class MapperExtension(object):
         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,
@@ -344,7 +344,7 @@ class MapperExtension(object):
 
         The return value is only significant within the ``MapperExtension`` 
         chain; the parent mapper's behavior isn't modified by this method.
-        
+
         """
 
         return EXT_CONTINUE
@@ -377,17 +377,17 @@ class MapperExtension(object):
 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!"
@@ -414,32 +414,32 @@ class SessionExtension(object):
 
     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 occured.
-        
+
         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 occured.
-        
+
         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."""
@@ -447,7 +447,7 @@ class SessionExtension(object):
     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
         occured, depending on whether or not the flush started its own
@@ -455,20 +455,20 @@ class SessionExtension(object):
 
     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.
@@ -476,9 +476,9 @@ class SessionExtension(object):
 
     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.
@@ -492,7 +492,7 @@ class AttributeExtension(object):
     .. 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
@@ -502,16 +502,16 @@ class AttributeExtension(object):
 
         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())
@@ -523,10 +523,10 @@ class AttributeExtension(object):
     ``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
@@ -535,7 +535,7 @@ class AttributeExtension(object):
 
     Note that ``active_history`` can also be set directly via
     :func:`.column_property` and :func:`.relationship`.
-    
+
     """
 
     @classmethod
@@ -549,7 +549,7 @@ class AttributeExtension(object):
         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.
 
index 06da99e0745a63c45ce9043454b343f3087b7bd8..e6166aa9ecc14282ce6c862c8542446f21e0c018 100644 (file)
@@ -6,7 +6,7 @@
 
 """Descriptor proprerties are more "auxilliary" properties
 that exist as configurational elements, but don't participate
-as actively in the load/persist ORM loop.   
+as actively in the load/persist ORM loop.
 
 """
 
@@ -20,23 +20,23 @@ 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_, **kw):
                     return prop.get_history(state, dict_, **kw)
-                
+
         if self.descriptor is None:
             desc = getattr(mapper.class_, self.key, None)
             if mapper._is_userland_descriptor(desc):
@@ -55,7 +55,7 @@ class DescriptorProperty(MapperProperty):
                 fset=fset,
                 fdel=fdel,
             )
-        
+
         proxy_attr = attributes.\
                     create_proxied_attribute(self.descriptor)\
                     (
@@ -68,10 +68,10 @@ class DescriptorProperty(MapperProperty):
         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_, *columns, **kwargs):
         self.columns = columns
         self.composite_class = class_
@@ -84,32 +84,32 @@ class CompositeProperty(DescriptorProperty):
     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._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)
-            
+
             # key not present, assume the columns aren't
             # loaded.  The load events will establish
             # the item.
             if self.key not in dict_:
                 for key in self._attribute_keys:
                     getattr(instance, key)
-                    
+
             return dict_.get(self.key, None)
-                
+
         def fset(instance, value):
             dict_ = attributes.instance_dict(instance)
             state = attributes.instance_state(instance)
@@ -126,7 +126,7 @@ class CompositeProperty(DescriptorProperty):
                         self._attribute_keys, 
                         value.__composite_values__()):
                     setattr(instance, key, value)
-        
+
         def fdel(instance):
             state = attributes.instance_state(instance)
             dict_ = attributes.instance_dict(instance)
@@ -135,13 +135,13 @@ class CompositeProperty(DescriptorProperty):
             attr.dispatch.remove(state, previous, attr.impl)
             for key in self._attribute_keys:
                 setattr(instance, key, None)
-        
+
         self.descriptor = property(fget, fset, fdel)
-        
+
     def _setup_arguments_on_columns(self):
         """Propagate configuration arguments made on this composite
         to the target columns, for those that apply.
-        
+
         """
         for col in self.columns:
             prop = self.parent._columntoproperty[col]
@@ -153,35 +153,35 @@ class CompositeProperty(DescriptorProperty):
 
     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', 
@@ -189,35 +189,35 @@ class CompositeProperty(DescriptorProperty):
         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 [
             self.parent._columntoproperty[col].key
             for col in self.columns
         ]
-        
+
     def get_history(self, state, dict_, **kw):
         """Provided for userland code that uses attributes.get_history()."""
-        
+
         added = []
         deleted = []
-        
+
         has_history = False
         for col in self.columns:
             key = self.parent._columntoproperty[col].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)],
@@ -236,7 +236,7 @@ class CompositeProperty(DescriptorProperty):
         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
@@ -244,9 +244,9 @@ class CompositeProperty(DescriptorProperty):
                             *[self.adapter(x) for x in self.prop.columns])
             else:
                 return expression.ClauseList(*self.prop.columns)
-        
+
         __hash__ = None
-        
+
         def __eq__(self, other):
             if other is None:
                 values = [None] * len(self.prop.columns)
@@ -254,7 +254,7 @@ class CompositeProperty(DescriptorProperty):
                 values = other.__composite_values__()
             return sql.and_(
                     *[a==b for a, b in zip(self.prop.columns, values)])
-            
+
         def __ne__(self, other):
             return sql.not_(self.__eq__(other))
 
@@ -280,14 +280,14 @@ class ConcreteInheritedProperty(DescriptorProperty):
 
     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 "
@@ -305,8 +305,8 @@ class ConcreteInheritedProperty(DescriptorProperty):
                     return self.descriptor
                 warn()
         self.descriptor = NoninheritedConcreteProp()
-        
-        
+
+
 class SynonymProperty(DescriptorProperty):
 
     def __init__(self, name, map_column=None, 
@@ -317,16 +317,16 @@ class SynonymProperty(DescriptorProperty):
         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
 
@@ -361,9 +361,9 @@ class SynonymProperty(DescriptorProperty):
                                     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."""
 
index 7d12900ccf8397895f664768b40173d0f34ecb00..8dbdd8ffe4f474a49e7420c028515f0025aa392f 100644 (file)
@@ -41,7 +41,7 @@ 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):
@@ -131,12 +131,12 @@ class DynamicAttributeImpl(attributes.AttributeImpl):
     def set_committed_value(self, state, dict_, value):
         raise NotImplementedError("Dynamic attributes don't support "
                                   "collection population.")
-    
+
     def get_history(self, state, dict_, passive=False):
         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 [
@@ -144,7 +144,7 @@ class DynamicAttributeImpl(attributes.AttributeImpl):
                 for x in 
                 c.added_items + c.unchanged_items + c.deleted_items
             ]
-        
+
     def _get_collection_history(self, state, passive=False):
         if self.key in state.committed_state:
             c = state.committed_state[self.key]
@@ -265,10 +265,10 @@ class AppenderMixin(object):
             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):
@@ -307,4 +307,4 @@ class CollectionHistory(object):
             self.deleted_items = []
             self.added_items = []
             self.unchanged_items = []
-    
+
index 5fe795db2e2e1c8d71249110fa2f64d5cee70591..761ba315dda017b6a78b14ce83f81386a56cfba9 100644 (file)
@@ -12,20 +12,20 @@ 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.  
+    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:
@@ -41,36 +41,36 @@ class InstrumentationEvents(event.Events):
 
     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.
-    
+
     Instance-level don't automatically propagate their associations
     to subclasses.
-    
+
     """
     @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):
@@ -85,7 +85,7 @@ class InstanceEvents(event.Events):
                 if manager:
                     return manager
         return None
-    
+
     @classmethod
     def _listen(cls, target, identifier, fn, raw=False, propagate=False):
         if not raw:
@@ -98,7 +98,7 @@ class InstanceEvents(event.Events):
         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")
@@ -107,26 +107,26 @@ class InstanceEvents(event.Events):
         """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
@@ -153,7 +153,7 @@ class InstanceEvents(event.Events):
     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
@@ -163,13 +163,13 @@ class InstanceEvents(event.Events):
         :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.
 
@@ -180,27 +180,27 @@ class InstanceEvents(event.Events):
         :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.
-        
+
         """
 
-        
+
 class MapperEvents(event.Events):
     """Define events specific to mappings.
 
     e.g.::
-    
+
         from sqlalchemy import event
 
         def my_before_insert_listener(mapper, connection, target):
@@ -209,7 +209,7 @@ class MapperEvents(event.Events):
             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)
@@ -221,13 +221,13 @@ class MapperEvents(event.Events):
     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
@@ -240,10 +240,10 @@ class MapperEvents(event.Events):
     :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.
@@ -256,7 +256,7 @@ class MapperEvents(event.Events):
        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
@@ -264,7 +264,7 @@ class MapperEvents(event.Events):
        * other values - the return value specified by specific listeners,
          such as :meth:`~.MapperEvents.translate_row` or 
          :meth:`~.MapperEvents.create_instance`.
-     
+
     """
 
     @classmethod
@@ -279,7 +279,7 @@ class MapperEvents(event.Events):
                 return class_mapper(target)
         else:
             return target
-        
+
     @classmethod
     def _listen(cls, target, identifier, fn, 
                             raw=False, retval=False, propagate=False):
@@ -292,7 +292,7 @@ class MapperEvents(event.Events):
                     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:
@@ -304,42 +304,42 @@ class MapperEvents(event.Events):
                 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.
@@ -352,7 +352,7 @@ class MapperEvents(event.Events):
         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
@@ -364,8 +364,8 @@ class MapperEvents(event.Events):
         :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_):
@@ -396,10 +396,10 @@ class MapperEvents(event.Events):
                         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
@@ -435,7 +435,7 @@ class MapperEvents(event.Events):
         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`.
@@ -462,12 +462,12 @@ class MapperEvents(event.Events):
     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.   
-        
+        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
@@ -476,7 +476,7 @@ class MapperEvents(event.Events):
         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
@@ -502,11 +502,11 @@ class MapperEvents(event.Events):
     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.   
+        connection.
 
         The event is often called for a batch of objects of the
         same class after their INSERT statements have been
@@ -528,7 +528,7 @@ class MapperEvents(event.Events):
          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):
@@ -538,7 +538,7 @@ class MapperEvents(event.Events):
         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.   
+        connection.
 
         This method is called for all instances that are
         marked as "dirty", *even those which have no net changes
@@ -553,7 +553,7 @@ class MapperEvents(event.Events):
         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,
@@ -567,7 +567,7 @@ class MapperEvents(event.Events):
         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
@@ -596,7 +596,7 @@ class MapperEvents(event.Events):
         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.   
+        connection.
 
         This method is called for all instances that are
         marked as "dirty", *even those which have no net changes
@@ -610,7 +610,7 @@ class MapperEvents(event.Events):
         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,
@@ -624,7 +624,7 @@ class MapperEvents(event.Events):
         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 
@@ -636,21 +636,21 @@ class MapperEvents(event.Events):
          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
@@ -670,17 +670,17 @@ class MapperEvents(event.Events):
          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. 
@@ -696,36 +696,36 @@ class MapperEvents(event.Events):
          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
-        
+
         class 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
@@ -748,39 +748,39 @@ class SessionEvents(event.Events):
             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 occured.
-        
+
         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 occured.
-        
+
         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."""
@@ -788,7 +788,7 @@ class SessionEvents(event.Events):
     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
         occured, depending on whether or not the flush started its own
@@ -796,20 +796,20 @@ class SessionEvents(event.Events):
 
     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.
@@ -817,9 +817,9 @@ class SessionEvents(event.Events):
 
     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.
@@ -828,37 +828,37 @@ class SessionEvents(event.Events):
 
 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
@@ -879,8 +879,8 @@ class AttributeEvents(event.Events):
       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.   
-    
+      or "append" event.
+
     """
 
     @classmethod
@@ -891,17 +891,17 @@ class AttributeEvents(event.Events):
             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):
@@ -913,21 +913,21 @@ class AttributeEvents(event.Events):
                 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.
 
@@ -942,7 +942,7 @@ class AttributeEvents(event.Events):
           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):
index a180f3725dbaa5bda83141a84a22811b1304d511..b86e5c7c387336afe4f0ad554ecbae79df742c88 100644 (file)
@@ -14,22 +14,22 @@ NO_STATE = (AttributeError, KeyError)
 
 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
 
 
@@ -43,7 +43,7 @@ class UnmappedError(sa.exc.InvalidRequestError):
 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."""
 
index 83687d682da643fa93fc77d4b9b45689c2ef7b8d..b3a7f8bc3fb79ca7bf727d961ee5658f1eb8c364 100644 (file)
@@ -15,30 +15,30 @@ class IdentityMap(dict):
         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 remove(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)  
+            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)
@@ -50,7 +50,7 @@ class IdentityMap(dict):
 
     def check_modified(self):
         """return True if any InstanceStates present have been marked as 'modified'."""
-        
+
         if self._modified:
             return True
         else:
@@ -58,10 +58,10 @@ class IdentityMap(dict):
                 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")
 
@@ -79,7 +79,7 @@ class IdentityMap(dict):
 
     def __delitem__(self, key):
         raise NotImplementedError("IdentityMap uses remove() to remove data")
-        
+
 class WeakInstanceDict(IdentityMap):
     def __init__(self):
         IdentityMap.__init__(self)
@@ -107,10 +107,10 @@ class WeakInstanceDict(IdentityMap):
             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)
@@ -118,7 +118,7 @@ class WeakInstanceDict(IdentityMap):
                 self._manage_removed_state(existing)
             else:
                 return
-                
+
         dict.__setitem__(self, state.key, state)
         self._manage_incoming_state(state)
 
@@ -146,7 +146,7 @@ class WeakInstanceDict(IdentityMap):
     def remove_key(self, key):
         state = dict.__getitem__(self, key)
         self.remove(state)
-        
+
     def remove(self, state):
         self._remove_mutex.acquire()
         try:
@@ -156,14 +156,14 @@ class WeakInstanceDict(IdentityMap):
                         "identity map" % state)
         finally:
             self._remove_mutex.release()
-            
+
         self._manage_removed_state(state)
-    
+
     def discard(self, state):
         if self.contains_state(state):
             dict.__delitem__(self, state.key)
             self._manage_removed_state(state)
-        
+
     def get(self, key, default=None):
         if not dict.__contains__(self, key):
             return default
@@ -178,7 +178,7 @@ class WeakInstanceDict(IdentityMap):
     def items(self):
     # Py2K
         return list(self.iteritems())
-    
+
     def iteritems(self):
     # end Py2K
         self._remove_mutex.acquire()
@@ -192,7 +192,7 @@ class WeakInstanceDict(IdentityMap):
             return iter(result)
         finally:
             self._remove_mutex.release()
-        
+
     def values(self):
     # Py2K
         return list(self.itervalues())
@@ -210,29 +210,29 @@ class WeakInstanceDict(IdentityMap):
             return iter(result)
         finally:
             self._remove_mutex.release()
-    
+
     def all_states(self):
         self._remove_mutex.acquire()
         try:
             # Py3K
             # return list(dict.values(self))
-        
+
             # Py2K
             return dict.values(self)
             # end Py2K
         finally:
             self._remove_mutex.release()
-            
+
     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)
@@ -255,26 +255,26 @@ class StrongInstanceDict(IdentityMap):
         else:
             dict.__setitem__(self, state.key, state.obj())
             self._manage_incoming_state(state)
-        
+
     def remove(self, state):
         if attributes.instance_state(dict.pop(self, state.key)) \
             is not state:
             raise AssertionError('State %s is not present in this '
                                  'identity map' % state)
         self._manage_removed_state(state)
-    
+
     def discard(self, state):
         if self.contains_state(state):
             dict.__delitem__(self, state.key)
             self._manage_removed_state(state)
-            
+
     def remove_key(self, key):
         state = attributes.instance_state(dict.__getitem__(self, key))
         self.remove(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]
 
@@ -286,4 +286,4 @@ class StrongInstanceDict(IdentityMap):
         dict.update(self, keepers)
         self.modified = bool(dirty)
         return ref_count - len(self)
-        
+
index 3ba9190c01a778cdd372eb3590021b9342670602..aa051490cf8959af4140e84b7c2ef6b04ca63122 100644 (file)
@@ -78,9 +78,9 @@ class ClassManager(dict):
     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
@@ -101,30 +101,30 @@ class ClassManager(dict):
 
         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
@@ -133,30 +133,30 @@ class ClassManager(dict):
         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 
@@ -166,12 +166,12 @@ class ClassManager(dict):
         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_)
@@ -179,15 +179,15 @@ class ClassManager(dict):
             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):
@@ -201,7 +201,7 @@ class ClassManager(dict):
             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)
@@ -214,11 +214,11 @@ class ClassManager(dict):
                 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
@@ -238,12 +238,12 @@ class ClassManager(dict):
 
     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)
@@ -304,15 +304,15 @@ class ClassManager(dict):
     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
@@ -329,7 +329,7 @@ class ClassManager(dict):
             state = self._state_constructor(instance, self)
             setattr(instance, self.STATE_ATTR, state)
             return state
-    
+
     def state_getter(self):
         """Return a (instance) -> InstanceState callable.
 
@@ -339,13 +339,13 @@ class ClassManager(dict):
         """
 
         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)
@@ -365,7 +365,7 @@ class _ClassInstrumentationAdapter(ClassManager):
         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):
@@ -427,10 +427,10 @@ class _ClassInstrumentationAdapter(ClassManager):
 
     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
@@ -445,7 +445,7 @@ class _ClassInstrumentationAdapter(ClassManager):
             return False
         else:
             return True
-            
+
     def state_getter(self):
         return self._get_state
 
@@ -454,7 +454,7 @@ class _ClassInstrumentationAdapter(ClassManager):
 
 def register_class(class_, **kw):
     """Register class instrumentation.
-    
+
     Returns the existing or newly created class manager.
     """
 
@@ -462,31 +462,31 @@ def register_class(class_, **kw):
     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()
@@ -518,23 +518,23 @@ class InstrumentationRegistry(object):
         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):
@@ -597,7 +597,7 @@ class InstrumentationRegistry(object):
         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_)
@@ -609,7 +609,7 @@ class InstrumentationRegistry(object):
             del self._dict_finders[class_]
         if ClassManager.MANAGER_ATTR in class_.__dict__:
             delattr(class_, ClassManager.MANAGER_ATTR)
-        
+
 instrumentation_registry = InstrumentationRegistry()
 
 
@@ -618,10 +618,10 @@ def _install_lookup_strategy(implementation):
     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'):
index 367344f5a94f526bf0c701c3a2755855eb31cedc..8cece65cce6cc1660ba2bad32ce2af74763ea27b 100644 (file)
@@ -65,9 +65,9 @@ class MapperProperty(object):
 
     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):
@@ -83,7 +83,7 @@ class MapperProperty(object):
     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
 
@@ -91,9 +91,9 @@ class MapperProperty(object):
                             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.
 
@@ -110,7 +110,7 @@ class MapperProperty(object):
 
     _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
@@ -131,10 +131,10 @@ class MapperProperty(object):
     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
@@ -188,7 +188,7 @@ class PropComparator(expression.ColumnOperators):
     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,\\
@@ -196,13 +196,13 @@ class PropComparator(expression.ColumnOperators):
 
         class MyColumnComparator(ColumnProperty.Comparator):
             pass
-        
+
         class MyCompositeComparator(CompositeProperty.Comparator):
             pass
-            
+
         class MyRelationshipComparator(RelationshipProperty.Comparator):
             pass
-    
+
     """
 
     def __init__(self, prop, mapper, adapter=None):
@@ -216,7 +216,7 @@ class PropComparator(expression.ColumnOperators):
     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)
@@ -291,9 +291,9 @@ class StrategizedProperty(MapperProperty):
     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:
@@ -334,7 +334,7 @@ class StrategizedProperty(MapperProperty):
         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)
@@ -344,7 +344,7 @@ def build_path(entity, key, prev=None):
 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]
@@ -366,14 +366,14 @@ class MapperOption(object):
     """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."""
 
@@ -440,7 +440,7 @@ class PropertyOption(MapperOption):
                         [str(m.path_entity) for m in query._entities]))
             else:
                 return None
-    
+
     def _get_paths(self, query, raiseerr):
         path = None
         entity = None
@@ -451,7 +451,7 @@ class PropertyOption(MapperOption):
         # existing path
 
         current_path = list(query._current_path)
-        
+
         tokens = deque(self.key)
         while tokens:
             token = tokens.popleft()
@@ -459,7 +459,7 @@ class PropertyOption(MapperOption):
                 sub_tokens = token.split(".", 1)
                 token = sub_tokens[0]
                 tokens.extendleft(sub_tokens[1:])
-        
+
                 if not entity:
                     if current_path:
                         if current_path[1] == token:
@@ -540,11 +540,11 @@ class StrategizedOption(PropertyOption):
 
 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 referened by Mapper.prop1.
-    
+
     """
     return tuple([i % 2 != 0 and 
                     element or 
@@ -595,7 +595,7 @@ class LoaderStrategy(object):
                                 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. """
 
@@ -617,7 +617,7 @@ class LoaderStrategy(object):
 
 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
@@ -626,13 +626,13 @@ class InstrumentationManager(object):
     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.
@@ -694,4 +694,3 @@ class InstrumentationManager(object):
 
     def dict_getter(self, class_):
         return lambda inst: self.get_instance_dict(class_, inst)
-        
\ No newline at end of file
index 5dc2fd83da0058e58b7099037c646a82fef7d005..8fe68fb8c0fd75e18f3ed398749e6ab8f0e13894 100644 (file)
@@ -26,7 +26,7 @@ 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
 
@@ -111,7 +111,7 @@ class Mapper(object):
             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 \
@@ -138,16 +138,16 @@ class Mapper(object):
         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)):
@@ -197,7 +197,7 @@ class Mapper(object):
             self.exclude_properties = None
 
         self.configured = False
-        
+
         # prevent this mapper from being constructed
         # while a configure_mappers() is occuring (and defer a configure_mappers()
         # until construction succeeds)
@@ -218,7 +218,7 @@ class Mapper(object):
             _COMPILE_MUTEX.release()
 
     dispatch = event.dispatcher(events.MapperEvents)
-            
+
     def _configure_inheritance(self):
         """Configure settings related to inherting and/or inherited mappers
         being present."""
@@ -322,12 +322,12 @@ class Mapper(object):
             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:
@@ -336,7 +336,7 @@ class Mapper(object):
                                     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)
@@ -351,7 +351,7 @@ class Mapper(object):
         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)
@@ -368,7 +368,7 @@ class Mapper(object):
 
         """
         manager = attributes.manager_of_class(self.class_)
-        
+
         if self.non_primary:
             if not manager or not manager.is_mapped:
                 raise sa_exc.InvalidRequestError(
@@ -392,7 +392,7 @@ class Mapper(object):
                 # 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_)
@@ -414,7 +414,7 @@ class Mapper(object):
         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__'):
@@ -425,31 +425,31 @@ class Mapper(object):
                         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:
@@ -465,7 +465,7 @@ class Mapper(object):
         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.
@@ -489,7 +489,7 @@ class Mapper(object):
             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:
@@ -497,7 +497,7 @@ class Mapper(object):
                 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:
@@ -535,7 +535,7 @@ class Mapper(object):
             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()
 
@@ -589,18 +589,18 @@ class Mapper(object):
         """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
 
@@ -624,7 +624,7 @@ class Mapper(object):
                     raise sa_exc.InvalidRequestError(
                         "Cannot exclude or override the discriminator column %r" %
                         col.key)
-                    
+
                 self._configure_property(
                                 col.key, 
                                 properties.ColumnProperty(col, _instrument=instrument),
@@ -642,7 +642,7 @@ class Mapper(object):
             self._set_polymorphic_identity = _set_polymorphic_identity
         else:
             self._set_polymorphic_identity = None
-        
+
 
 
     def _adapt_inherited_property(self, key, prop, init):
@@ -653,7 +653,7 @@ class Mapper(object):
                             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__)
 
@@ -684,7 +684,7 @@ class Mapper(object):
                 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:
@@ -722,7 +722,7 @@ class Mapper(object):
 
         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]
@@ -737,7 +737,7 @@ class Mapper(object):
                                                 prop.columns[0])
                         break
                     path.append(m)
-                
+
             # otherwise, col might not be present! the selectable given 
             # to the mapper need not include "deferred"
             # columns (included in zblog tests)
@@ -758,7 +758,7 @@ class Mapper(object):
                                     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.
@@ -766,7 +766,7 @@ class Mapper(object):
                 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:
@@ -785,7 +785,7 @@ class Mapper(object):
                         "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:
@@ -805,23 +805,23 @@ class Mapper(object):
 
         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`.
@@ -904,19 +904,19 @@ class Mapper(object):
         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."""
@@ -957,7 +957,7 @@ class Mapper(object):
         mapped tables.
 
         """
-        
+
         from_obj = self.mapped_table
         for m in mappers:
             if m is self:
@@ -1023,7 +1023,7 @@ class Mapper(object):
     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
 
@@ -1043,7 +1043,7 @@ class Mapper(object):
                         c.columns[0] is not self.polymorphic_on):
                         continue
                 yield c
-    
+
     @property
     def properties(self):
         raise NotImplementedError(
@@ -1109,7 +1109,7 @@ class Mapper(object):
                     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
@@ -1208,13 +1208,13 @@ class Mapper(object):
     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.
@@ -1261,7 +1261,7 @@ class Mapper(object):
                 impl.get(state, dict_, False)
             for col in self.primary_key
         ])
-        
+
     def primary_key_from_instance(self, instance):
         """Return the list of primary key values for the given
         instance.
@@ -1294,7 +1294,7 @@ class Mapper(object):
 
     def _get_committed_state_attr_by_column(self, state, dict_, column,
                                                     passive=False):
-                                                    
+
         prop = self._columntoproperty[column]
         return state.manager[prop.key].impl.\
                     get_committed_value(state, dict_, passive=passive)
@@ -1302,21 +1302,21 @@ class Mapper(object):
     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
 
@@ -1396,7 +1396,7 @@ class Mapper(object):
             if not iterator:
                 visitables.pop()
                 continue
-                
+
             if item_type is prp:
                 prop = iterator.popleft()
                 if type_ not in prop.cascade:
@@ -1422,7 +1422,7 @@ class Mapper(object):
         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_:
@@ -1433,15 +1433,15 @@ class Mapper(object):
         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)
@@ -1454,20 +1454,20 @@ class Mapper(object):
             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(
@@ -1492,7 +1492,7 @@ class Mapper(object):
                 conn = connection
 
             mapper = _state_mapper(state)
-                
+
             tups.append((state, state.dict, mapper, conn))
 
         table_to_mapper = self._sorted_tables
@@ -1503,7 +1503,7 @@ class Mapper(object):
             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
@@ -1525,7 +1525,7 @@ class Mapper(object):
                 if hasdata:
                     update.append((state, state_dict, params, mapper, 
                                     connection))
-        
+
             if update:
                 mapper = table_to_mapper[table]
 
@@ -1551,7 +1551,7 @@ class Mapper(object):
                                             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.
@@ -1562,7 +1562,7 @@ class Mapper(object):
         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):
@@ -1582,19 +1582,19 @@ class Mapper(object):
             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)
@@ -1648,14 +1648,14 @@ class Mapper(object):
                             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]:
@@ -1667,7 +1667,7 @@ class Mapper(object):
                             # 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
@@ -1772,7 +1772,7 @@ class Mapper(object):
 
                 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))
@@ -1783,13 +1783,13 @@ class Mapper(object):
                                                 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),
@@ -1797,7 +1797,7 @@ class Mapper(object):
                     else:
                         c = cached_connections[connection].\
                                             execute(statement, params)
-                    
+
                     mapper._postfetch(
                             uowtransaction, 
                             table, 
@@ -1821,7 +1821,7 @@ class Mapper(object):
                             "- versioning cannot be verified." % 
                             c.dialect.dialect_description,
                             stacklevel=12)
-                    
+
             if insert:
                 statement = self._memo(('insert', table), table.insert)
 
@@ -1837,7 +1837,7 @@ class Mapper(object):
                         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 \
@@ -1851,7 +1851,7 @@ class Mapper(object):
                                     c.context.postfetch_cols,
                                     last_inserted_params, 
                                     value_params)
-                            
+
                     else:
                         for state, state_dict, params, mapper, \
                                     connection, value_params, \
@@ -1864,7 +1864,7 @@ class Mapper(object):
                             else:
                                 result = cached_connections[connection].\
                                                     execute(statement, params)
-                    
+
                             primary_key = result.context.inserted_primary_key
 
                             if primary_key is not None:
@@ -1942,14 +1942,14 @@ class Mapper(object):
                                             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():
@@ -1957,9 +1957,9 @@ class Mapper(object):
                     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.
 
@@ -1973,13 +1973,13 @@ class Mapper(object):
         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)
 
@@ -1987,9 +1987,9 @@ class Mapper(object):
                 conn = connection_callable(self, state.obj())
             else:
                 conn = connection
-        
+
             mapper.dispatch.before_delete(mapper, conn, state)
-            
+
             tups.append((state, 
                     state.dict,
                     _state_mapper(state), 
@@ -1997,7 +1997,7 @@ class Mapper(object):
                     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:
@@ -2080,10 +2080,10 @@ class Mapper(object):
                                 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:
@@ -2112,7 +2112,7 @@ class Mapper(object):
         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:
@@ -2125,7 +2125,7 @@ class Mapper(object):
                                 new_populators,
                                 existing_populators
                 )
-            
+
             if isnew:
                 populators = new_populators
             else:
@@ -2142,7 +2142,7 @@ class Mapper(object):
         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
@@ -2152,7 +2152,7 @@ class Mapper(object):
             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:
@@ -2160,7 +2160,7 @@ class Mapper(object):
                     if ret is not EXT_CONTINUE:
                         row = ret
                         break
-                        
+
             if polymorphic_on is not None:
                 discriminator = row[polymorphic_on]
                 if discriminator is not None:
@@ -2196,7 +2196,7 @@ class Mapper(object):
                                 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'." 
@@ -2268,7 +2268,7 @@ class Mapper(object):
                         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:
@@ -2286,8 +2286,8 @@ class Mapper(object):
                     isnew = True
                     attrs = state.unloaded
                     # allow query.instances to commit the subset of attrs
-                    context.partials[state] = (dict_, attrs)  
-                
+                    context.partials[state] = (dict_, attrs)
+
                 if populate_instance:
                     for fn in populate_instance:
                         ret = fn(self, context, row, state, 
@@ -2299,11 +2299,11 @@ class Mapper(object):
                         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:
@@ -2322,7 +2322,7 @@ class Mapper(object):
     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(
@@ -2337,11 +2337,11 @@ class Mapper(object):
                 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]
@@ -2351,16 +2351,16 @@ class Mapper(object):
                         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,
@@ -2375,7 +2375,7 @@ def configure_mappers():
 
     This function can be called any number of times, but in 
     most cases is handled internally.
-    
+
     """
 
     global _new_mappers
@@ -2453,7 +2453,7 @@ def validates(*names):
     can then raise validation exceptions to halt the process from continuing,
     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
@@ -2477,7 +2477,7 @@ def _event_on_first_init(manager, cls):
     if instrumenting_mapper:
         if _new_mappers:
             configure_mappers()
-    
+
 def _event_on_init(state, args, kwargs):
     """Run init_instance hooks."""
 
@@ -2494,14 +2494,14 @@ def _event_on_resurrect(state):
         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:
@@ -2511,7 +2511,7 @@ def _load_scalar_attributes(state, attribute_names):
                     (state_str(state)))
 
     has_key = bool(state.key)
-    
+
     result = False
 
     if mapper.inherits and not mapper.concrete:
@@ -2536,7 +2536,7 @@ def _load_scalar_attributes(state, attribute_names):
                                                 " 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):
@@ -2545,7 +2545,7 @@ def _load_scalar_attributes(state, attribute_names):
                         "(and shouldn't be expired, either)." 
                         % state_str(state))
             return
-        
+
         result = session.query(mapper)._load_on_ident(
                                             identity_key, 
                                             refresh_state=state, 
index 9f2d6336446492676b366bdcd845d450e33576d1..813be60ce99504cecd347769ae1243b4c6d78a53 100644 (file)
@@ -62,7 +62,7 @@ class ColumnProperty(StrategizedProperty):
         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:
@@ -73,7 +73,7 @@ class ColumnProperty(StrategizedProperty):
                     break
             else:
                 self.doc = None
-        
+
         if kwargs:
             raise TypeError(
                 "%s received unexpected keyword argument(s): %s" % (
@@ -87,11 +87,11 @@ class ColumnProperty(StrategizedProperty):
             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, 
@@ -100,7 +100,7 @@ class ColumnProperty(StrategizedProperty):
             property_=self,
             doc=self.doc
             )
-        
+
     def do_init(self):
         super(ColumnProperty, self).do_init()
         if len(self.columns) > 1 and \
@@ -127,7 +127,7 @@ class ColumnProperty(StrategizedProperty):
                                 dest_dict, load, _recursive):
         if self.key in source_dict:
             value = source_dict[self.key]
-        
+
             if not load:
                 dest_dict[self.key] = value
             else:
@@ -136,7 +136,7 @@ class ColumnProperty(StrategizedProperty):
         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):
@@ -146,17 +146,17 @@ class ColumnProperty(StrategizedProperty):
                 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
 
@@ -222,7 +222,7 @@ class RelationshipProperty(StrategizedProperty):
                                     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':
@@ -230,7 +230,7 @@ class RelationshipProperty(StrategizedProperty):
             self.strategy_class = dynamic.DynaLoader
         else:
             self.strategy_class = strategies.factory(self.lazy)
-            
+
         self._reverse_property = set()
 
         if cascade is not False:
@@ -280,13 +280,13 @@ class RelationshipProperty(StrategizedProperty):
             """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
@@ -314,9 +314,9 @@ class RelationshipProperty(StrategizedProperty):
             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]:
@@ -352,7 +352,7 @@ class RelationshipProperty(StrategizedProperty):
                 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,
@@ -364,7 +364,7 @@ class RelationshipProperty(StrategizedProperty):
                     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.
@@ -372,7 +372,7 @@ class RelationshipProperty(StrategizedProperty):
                 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)
@@ -384,9 +384,9 @@ class RelationshipProperty(StrategizedProperty):
             # 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):
@@ -422,26 +422,26 @@ class RelationshipProperty(StrategizedProperty):
         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,
@@ -531,11 +531,11 @@ class RelationshipProperty(StrategizedProperty):
             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.  
+                # 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)
@@ -545,7 +545,7 @@ class RelationshipProperty(StrategizedProperty):
                         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)
@@ -582,28 +582,28 @@ class RelationshipProperty(StrategizedProperty):
         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 "
@@ -616,13 +616,13 @@ class RelationshipProperty(StrategizedProperty):
             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 '
@@ -634,7 +634,7 @@ class RelationshipProperty(StrategizedProperty):
                     '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()
@@ -667,7 +667,7 @@ class RelationshipProperty(StrategizedProperty):
                         % (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
@@ -783,23 +783,23 @@ class RelationshipProperty(StrategizedProperty):
         """Given a join condition, figure out what columns are foreign
         and are part of a binary "equated" condition to their referecned
         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:
@@ -822,12 +822,12 @@ class RelationshipProperty(StrategizedProperty):
                                 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 "\
@@ -836,7 +836,7 @@ class RelationshipProperty(StrategizedProperty):
                             join_condition, 
                             self
                         )
-                
+
                 if not self._user_defined_foreign_keys:
                     err += "  Ensure that the "\
                             "referencing Column objects have a "\
@@ -844,7 +844,7 @@ class RelationshipProperty(StrategizedProperty):
                             "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."
@@ -981,7 +981,7 @@ class RelationshipProperty(StrategizedProperty):
             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:
@@ -1054,7 +1054,7 @@ class RelationshipProperty(StrategizedProperty):
                     "created for class '%s' " % (self.key,
                     self.parent.class_.__name__,
                     self.parent.class_.__name__))
-            
+
     def _generate_backref(self):
         if not self.is_primary():
             return
@@ -1099,7 +1099,7 @@ class RelationshipProperty(StrategizedProperty):
             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)
@@ -1121,7 +1121,7 @@ class RelationshipProperty(StrategizedProperty):
         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
@@ -1129,7 +1129,7 @@ class RelationshipProperty(StrategizedProperty):
 
         strategy = self._get_strategy(strategies.LazyLoader)
         return strategy.use_get
-        
+
     def _refers_to_parent_table(self):
         for c, f in self.synchronize_pairs:
             if c.table is f.table:
@@ -1169,21 +1169,21 @@ class RelationshipProperty(StrategizedProperty):
 
         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 analgous 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()
index 53c777ae842818cc85227c193785b8ad23754145..d5f0ef0ca5799726781cb9fcf8c32cd4723717f8 100644 (file)
@@ -55,20 +55,20 @@ def _generative(*assertions):
 
 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
@@ -100,7 +100,7 @@ class Query(object):
     _with_options = ()
     _with_hints = ()
     _enable_single_crit = True
-    
+
     def __init__(self, entities, session=None):
         self.session = session
         self._polymorphic_adapters = {}
@@ -173,7 +173,7 @@ class Query(object):
             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, 
@@ -226,7 +226,7 @@ class Query(object):
     @_generative()
     def _adapt_all_clauses(self):
         self._disable_orm_filtering = True
-    
+
     def _adapt_col_list(self, cols):
         return [
                     self._adapt_clause(
@@ -234,7 +234,7 @@ class Query(object):
                                 True, True) 
                     for o in cols
                 ]
-        
+
     def _adapt_clause(self, clause, as_filter, orm_only):
         adapters = []
         if as_filter and self._filter_aliases:
@@ -323,7 +323,7 @@ class Query(object):
     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
@@ -407,11 +407,11 @@ class Query(object):
     @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).\
@@ -432,33 +432,33 @@ class Query(object):
 
         """
         return self.enable_eagerloads(False).statement.alias()
-    
+
     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.
-        
+
         Analagous 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.
-        
+
         Analagous 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
 
@@ -495,11 +495,11 @@ class Query(object):
 
         """
         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
@@ -509,22 +509,22 @@ class Query(object):
         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
 
@@ -601,12 +601,12 @@ class Query(object):
         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.
@@ -621,9 +621,9 @@ class Query(object):
         # convert composite types to individual args
         if hasattr(ident, '__composite_values__'):
             ident = ident.__composite_values__()
-        
+
         ident = util.to_list(ident)
-        
+
         mapper = self._only_mapper_zero(
                     "get() can only be used against a single mapped class."
                 )
@@ -633,13 +633,13 @@ class Query(object):
             "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
@@ -655,22 +655,22 @@ class Query(object):
         """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)
@@ -691,7 +691,7 @@ class Query(object):
     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
@@ -706,16 +706,16 @@ class Query(object):
         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)
@@ -767,7 +767,7 @@ class Query(object):
     @_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',
@@ -805,12 +805,12 @@ class Query(object):
             # 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
@@ -830,11 +830,11 @@ class Query(object):
                         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 
@@ -853,23 +853,23 @@ class Query(object):
                 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 superceded 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)
 
@@ -894,7 +894,7 @@ class Query(object):
     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 
@@ -902,16 +902,16 @@ class Query(object):
         /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:`sqlalchemy.sql.expression.Executable.execution_options`.
-        
+
         Note that the ``stream_results`` execution option is enabled
         automatically if the :meth:`~sqlalchemy.orm.query.Query.yield_per()`
         method is used.
@@ -982,16 +982,16 @@ class Query(object):
     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:
@@ -1002,7 +1002,7 @@ class Query(object):
             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:
@@ -1075,8 +1075,8 @@ class Query(object):
                             SELECT * FROM Z)
 
         """
-        
-        
+
+
         return self._from_selectable(
                     expression.union(*([self]+ list(q))))
 
@@ -1200,15 +1200,15 @@ class Query(object):
             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)
@@ -1239,13 +1239,13 @@ class Query(object):
     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 \
@@ -1264,7 +1264,7 @@ class Query(object):
                 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
@@ -1275,19 +1275,19 @@ class Query(object):
                 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:
@@ -1304,9 +1304,9 @@ class Query(object):
                         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
@@ -1324,7 +1324,7 @@ class Query(object):
             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, 
@@ -1333,7 +1333,7 @@ class Query(object):
     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()
 
@@ -1343,7 +1343,7 @@ class Query(object):
                         "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)
 
@@ -1410,7 +1410,7 @@ class Query(object):
             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.
@@ -1423,7 +1423,7 @@ class Query(object):
         # 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
@@ -1436,7 +1436,7 @@ class Query(object):
                             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
@@ -1446,7 +1446,7 @@ class Query(object):
         # 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, 
@@ -1457,13 +1457,13 @@ class Query(object):
                 # 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, 
@@ -1491,7 +1491,7 @@ class Query(object):
 
         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):
@@ -1513,16 +1513,16 @@ class Query(object):
     @_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:
@@ -1534,10 +1534,10 @@ class Query(object):
                 raise sa_exc.ArgumentError(
                             "select_from() accepts FromClause objects only.")
             else:
-                obj.append(fo)  
-                
+                obj.append(fo)
+
         self._set_select_from(*obj)
-        
+
     def __getitem__(self, item):
         if isinstance(item, slice):
             start, stop, step = util.decode_slice(item)
@@ -1568,7 +1568,7 @@ class Query(object):
     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
@@ -1637,7 +1637,7 @@ class Query(object):
     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 
@@ -1663,7 +1663,7 @@ class Query(object):
         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 
@@ -1676,7 +1676,7 @@ class Query(object):
 
         """
         ret = list(self)
-        
+
         l = len(ret)
         if l == 1:
             return ret[0]
@@ -1726,20 +1726,20 @@ class Query(object):
                         clause = querycontext.statement,
                         close_with_result=True).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:
             [
                 {
@@ -1761,7 +1761,7 @@ class Query(object):
                     'expr':user_alias
                 }
             ]
-            
+
         """
         return [
             {
@@ -1772,7 +1772,7 @@ class Query(object):
             }
             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.
@@ -1810,8 +1810,8 @@ class Query(object):
                         query_entity.row_processor(self, context, custom_rows)
                         for query_entity in self._entities
                     ])
-            
-        
+
+
         while True:
             context.progress = {}
             context.partials = {}
@@ -1855,7 +1855,7 @@ class Query(object):
 
     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
@@ -1863,19 +1863,19 @@ class Query(object):
         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
@@ -1900,23 +1900,23 @@ class Query(object):
                                 attributes.instance_state(newrow[i]), 
                                 attributes.instance_dict(newrow[i]), 
                                 load=load, _recursive={})
-                    result.append(util.NamedTuple(newrow, row._labels))  
-            
+                    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:
@@ -1930,18 +1930,18 @@ class Query(object):
             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()
@@ -1952,7 +1952,7 @@ class Query(object):
             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:
@@ -1962,7 +1962,7 @@ class Query(object):
                             ])
                 _get_clause = sql_util.adapt_criterion_to_null(
                                                 _get_clause, nones)
-                
+
             _get_clause = q._adapt_clause(_get_clause, True, False)
             q._criterion = _get_clause
 
@@ -2006,7 +2006,7 @@ class Query(object):
 
     def count(self):
         """Return a count of rows this Query would return.
-        
+
         For simple entity queries, count() issues
         a SELECT COUNT, and will specifically count the primary
         key column of the first entity only.  If the query uses 
@@ -2014,11 +2014,11 @@ class Query(object):
         generated by this Query in a subquery, from which a SELECT COUNT
         is issued, so that the contract of "how many rows
         would be returned?" is honored.
-        
+
         For queries that request specific columns or expressions, 
         count() again makes no assumptions about those expressions
         and will wrap everything in a subquery.  Therefore,
-        ``Query.count()`` is usually not what you want in this case.   
+        ``Query.count()`` is usually not what you want in this case.
         To count specific columns, often in conjunction with 
         GROUP BY, use ``func.count()`` as an individual column expression
         instead of ``Query.count()``.  See the ORM tutorial
@@ -2081,7 +2081,7 @@ class Query(object):
 
         :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
@@ -2099,7 +2099,7 @@ class Query(object):
             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.
 
@@ -2149,7 +2149,7 @@ class Query(object):
                 else:
                     def eval_condition(obj):
                         return True
-                    
+
             except evaluator.UnevaluatableError:
                 raise sa_exc.InvalidRequestError(
                     "Could not evaluate current criteria in Python.  "
@@ -2214,7 +2214,7 @@ class Query(object):
             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.
@@ -2254,7 +2254,7 @@ class Query(object):
                                     "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 "
@@ -2342,7 +2342,7 @@ class Query(object):
                                 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
@@ -2367,21 +2367,21 @@ class Query(object):
 
         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)  
+            froms = list(context.from_clause)
         else:
             # "load from discrete FROMs" mode, 
             # i.e. when each _MappedEntity has its own FROM
-            froms = context.froms   
+            froms = context.froms
 
         if self._enable_single_crit:
             self._adjust_for_single_inheritance(context)
@@ -2422,10 +2422,10 @@ class Query(object):
                         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)
 
@@ -2439,7 +2439,7 @@ class Query(object):
                                 [inner] + context.secondary_columns, 
                                 for_update=for_update, 
                                 use_labels=labels)
-                                
+
             if self._execution_options:
                 statement = statement.execution_options(
                                                 **self._execution_options)
@@ -2492,7 +2492,7 @@ class Query(object):
 
             for hint in self._with_hints:
                 statement = statement.with_hint(*hint)
-                    
+
             if self._execution_options:
                 statement = statement.execution_options(
                                             **self._execution_options)
@@ -2516,7 +2516,7 @@ class Query(object):
         selected from the total results.
 
         """
-            
+
         for entity, (mapper, adapter, s, i, w) in \
                             self._mapper_adapter_map.iteritems():
             single_crit = mapper._single_table_criterion
@@ -2558,7 +2558,7 @@ class _MapperEntity(_QueryEntity):
 
         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
@@ -2578,8 +2578,8 @@ class _MapperEntity(_QueryEntity):
             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:
@@ -2611,14 +2611,14 @@ class _MapperEntity(_QueryEntity):
         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)
@@ -2666,7 +2666,7 @@ class _MapperEntity(_QueryEntity):
                                     self._polymorphic_discriminator)
 
         return _instance, self._label_name
-    
+
     def setup_context(self, query, context):
         adapter = self._get_entity_clauses(query, context)
 
@@ -2688,7 +2688,7 @@ class _MapperEntity(_QueryEntity):
                 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:
@@ -2718,7 +2718,7 @@ class _ColumnEntity(_QueryEntity):
 
     def __init__(self, query, column):
         self.expr = column
-        
+
         if isinstance(column, basestring):
             column = sql.literal_column(column)
             self._label_name = column.name
@@ -2779,17 +2779,17 @@ class _ColumnEntity(_QueryEntity):
             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
@@ -2834,7 +2834,7 @@ class QueryContext(object):
     multi_row_eager_loaders = False
     adapter = None
     froms = ()
-    
+
     def __init__(self, query):
 
         if query._statement is not None:
index 431377da0a43142bc69762080658b31e5c5b3f13..1068f670452b2165147c4e0791bf66c3de6f23c6 100644 (file)
@@ -22,10 +22,10 @@ class ScopedSession(object):
       Session = scoped_session(sessionmaker())
 
     ... use Session normally.
-      
+
     The internal registry is accessible as well,
     and by default is an instance of :class:`.ThreadLocalRegistry`.
-      
+
 
     """
 
@@ -54,14 +54,14 @@ class ScopedSession(object):
 
     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 '
@@ -74,7 +74,7 @@ class ScopedSession(object):
         class when called.
 
         e.g.::
-        
+
             Session = scoped_session(sessionmaker())
 
             class MyClass(object):
index 942b4d684ec753fa9d68bd23b1491183a6c1d1a1..47420e207f7b88bf8d546cb2b69f50ab53d24839 100644 (file)
@@ -138,7 +138,7 @@ def sessionmaker(bind=None, class_=None, autoflush=True, autocommit=False,
     :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.**  
+       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,
@@ -190,8 +190,8 @@ def sessionmaker(bind=None, class_=None, autoflush=True, autocommit=False,
                 Session.configure(bind=create_engine('sqlite://'))
             """
             kwargs.update(new_kwargs)
-        
-        
+
+
     return type("Session", (Sess, class_), {})
 
 
@@ -211,9 +211,9 @@ class SessionTransaction(object):
       single: thread safety; SessionTransaction
 
     """
-    
+
     _rollback_exception = None
-    
+
     def __init__(self, session, parent=None, nested=False):
         self.session = session
         self._connections = {}
@@ -297,7 +297,7 @@ class SessionTransaction(object):
 
         for s in set(self._new).union(self.session._new):
             self.session._expunge_state(s)
-            
+
         for s in set(self._deleted).union(self.session._deleted):
             if s.deleted:
                 # assert s in self._deleted
@@ -465,7 +465,7 @@ class Session(object):
     """Manages persistence operations for ORM-mapped objects.
 
     The Session's usage paradigm is described at :ref:`session_toplevel`.
-    
+
     """
 
     public_methods = (
@@ -475,8 +475,8 @@ class Session(object):
         '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, 
@@ -489,7 +489,7 @@ class Session(object):
         typical point of entry.
 
         """
-        
+
         if weak_identity_map:
             self._identity_cls = identity.WeakInstanceDict
         else:
@@ -509,11 +509,11 @@ class Session(object):
         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)):
@@ -528,7 +528,7 @@ class Session(object):
     dispatch = event.dispatcher(SessionEvents)
 
     connection_callable = None
-    
+
     def begin(self, subtransactions=False, nested=False):
         """Begin a transaction on this Session.
 
@@ -537,9 +537,9 @@ class Session(object):
         ``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.  
+        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`.
@@ -588,12 +588,12 @@ class Session(object):
 
     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.  
+        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
@@ -692,7 +692,7 @@ class Session(object):
         will be created for the life of the result (i.e., a connection is
         checked out from the connection pool, which is returned when the
         result object is closed).
-        
+
         If the :class:`Session` is not bound to an
         :class:`~sqlalchemy.engine.base.Engine` or
         :class:`~sqlalchemy.engine.base.Connection`, the given clause will be
@@ -702,7 +702,7 @@ class Session(object):
         (since the :class:`Session` keys multiple bind sources to a series of
         :func:`mapper` objects). See :meth:`get_bind` for further details on
         bind resolution.
-        
+
         :param clause:
             A ClauseElement (i.e. select(), text(), etc.) or
             string SQL statement to be executed
@@ -716,7 +716,7 @@ class Session(object):
         :param \**kw:
           Additional keyword arguments are sent to :meth:`get_bind()`
           which locates a connectable to use for the execution.
-          
+
         """
         clause = expression._literal_as_text(clause)
 
@@ -727,7 +727,7 @@ class Session(object):
 
     def scalar(self, clause, params=None, mapper=None, **kw):
         """Like execute() but return a scalar result."""
-        
+
         return self.execute(clause, params=params, mapper=mapper, **kw).scalar()
 
     def close(self):
@@ -826,7 +826,7 @@ class Session(object):
                     "a binding.")
 
         c_mapper = mapper is not None and _class_to_mapper(mapper) or None
-        
+
         # manually bound?
         if self.__binds:
             if c_mapper:
@@ -853,7 +853,7 @@ class Session(object):
             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)))
@@ -890,14 +890,14 @@ class Session(object):
         :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)
@@ -916,7 +916,7 @@ class Session(object):
 
     def expire_all(self):
         """Expires all persistent instances within this Session.
-        
+
         When any attributes on a persitent instance is next accessed, 
         a query will be issued using the
         :class:`.Session` object's current transactional context in order to
@@ -927,7 +927,7 @@ class Session(object):
 
         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
@@ -949,10 +949,10 @@ class Session(object):
         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
@@ -971,7 +971,7 @@ class Session(object):
         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:
@@ -984,16 +984,16 @@ class Session(object):
             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()
-        
+
     def prune(self):
         """Remove unreferenced instances cached in the identity map.
 
@@ -1046,7 +1046,7 @@ class Session(object):
         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]):
@@ -1063,10 +1063,10 @@ class Session(object):
                 # 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:
@@ -1132,7 +1132,7 @@ class Session(object):
 
         if state in self._deleted:
             return
-            
+
         # ensure object is attached to allow the 
         # cascade operation to load deferred attributes
         # and collections
@@ -1164,19 +1164,19 @@ class Session(object):
         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:
@@ -1187,7 +1187,7 @@ class Session(object):
                             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:
@@ -1195,7 +1195,7 @@ class Session(object):
 
         new_instance = False
         key = state.key
-        
+
         if key is None:
             if not load:
                 raise sa_exc.InvalidRequestError(
@@ -1207,7 +1207,7 @@ class Session(object):
 
         if key in self.identity_map:
             merged = self.identity_map[key]
-            
+
         elif not load:
             if state.modified:
                 raise sa_exc.InvalidRequestError(
@@ -1219,14 +1219,14 @@ class Session(object):
             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)
@@ -1236,15 +1236,15 @@ class Session(object):
         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.   
+        # state out.
         if state is not merged_state:
             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, 
@@ -1252,7 +1252,7 @@ class Session(object):
 
         if not load:
             # remove any history
-            merged_state.commit_all(merged_dict, self.identity_map)  
+            merged_state.commit_all(merged_dict, self.identity_map)
 
         if new_instance:
             merged_state.manager.dispatch.load(merged_state)
@@ -1279,7 +1279,7 @@ class Session(object):
             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()
@@ -1289,12 +1289,12 @@ class Session(object):
         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() "
@@ -1317,11 +1317,11 @@ class Session(object):
 
         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 \
@@ -1330,13 +1330,13 @@ class Session(object):
                     "%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:
@@ -1393,16 +1393,16 @@ class Session(object):
                 "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):
@@ -1414,13 +1414,13 @@ class Session(object):
             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)
 
@@ -1448,7 +1448,7 @@ class Session(object):
             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)
@@ -1475,7 +1475,7 @@ class Session(object):
         except:
             transaction.rollback(_capture_exception=True)
             raise
-        
+
         flush_context.finalize_flush_changes()
 
         # useful assertions:
@@ -1485,7 +1485,7 @@ class Session(object):
         #    assert self.identity_map._modified == \
         #            self.identity_map._modified.difference(objects)
         #self.identity_map._modified.clear()
-        
+
         self.dispatch.after_flush_postexec(self, flush_context)
 
     def is_modified(self, instance, include_collections=True, passive=False):
@@ -1493,7 +1493,7 @@ class Session(object):
 
         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.  
+        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
@@ -1503,9 +1503,9 @@ class Session(object):
 
         The ``passive`` flag indicates if unloaded attributes and collections
         should not be loaded in the course of performing this test.
-        
+
         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
@@ -1520,7 +1520,7 @@ class Session(object):
           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
@@ -1539,10 +1539,10 @@ class Session(object):
                     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
@@ -1604,18 +1604,18 @@ _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)
@@ -1629,19 +1629,19 @@ def make_transient(instance):
         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:
index 974b3d5003e5d32a3d0cd4b4314d9b56893cd58e..da91a353eb1c9cd334fcfbd4e6506a2fbbede6bc 100644 (file)
@@ -37,14 +37,14 @@ class InstanceState(object):
     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 {}
@@ -56,14 +56,14 @@ class InstanceState(object):
     @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:
@@ -71,14 +71,14 @@ class InstanceState(object):
                 instance_dict.remove(self)
             except AssertionError:
                 pass
-                
+
         self.callables = {}
         self.session_id = None
         del self.obj
-        
+
     def obj(self):
         return None
-    
+
     @property
     def dict(self):
         o = self.obj()
@@ -86,7 +86,7 @@ class InstanceState(object):
             return attributes.instance_dict(o)
         else:
             return {}
-        
+
     @property
     def sort_key(self):
         return self.key and self.key[1] or (self.insert_order, )
@@ -96,7 +96,7 @@ class InstanceState(object):
         manager = self.manager
 
         manager.dispatch.init(self, args, kwargs)
-            
+
         #if manager.mutable_attributes:
         #    assert self.__class__ is MutableAttrInstanceState
 
@@ -148,7 +148,7 @@ class InstanceState(object):
         if self.load_path:
             d['load_path'] = interfaces.serialize_path(self.load_path)
         return d
-        
+
     def __setstate__(self, state):
         from sqlalchemy.orm import instrumentation
         self.obj = weakref.ref(state['instance'], self._cleanup)
@@ -162,17 +162,17 @@ class InstanceState(object):
                         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'
@@ -181,13 +181,13 @@ class InstanceState(object):
 
         if 'load_path' in state:
             self.load_path = interfaces.deserialize_path(state['load_path'])
-        
+
         # TODO: need an event here, link to composite, mutable
-        
+
     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):
@@ -212,10 +212,10 @@ class InstanceState(object):
     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:
@@ -230,26 +230,26 @@ class InstanceState(object):
             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)
@@ -267,10 +267,10 @@ class InstanceState(object):
 
         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 
@@ -279,13 +279,13 @@ class InstanceState(object):
         # 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):
@@ -311,11 +311,11 @@ class InstanceState(object):
     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.  
-           
+           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])
 
@@ -324,24 +324,24 @@ class InstanceState(object):
 
     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:
@@ -350,7 +350,7 @@ class InstanceState(object):
             self._strong_obj = self.obj()
 
             self.modified = True
-        
+
     def commit(self, dict_, keys):
         """Commit attributes.
 
@@ -371,14 +371,14 @@ class InstanceState(object):
         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.
 
@@ -402,30 +402,30 @@ class InstanceState(object):
         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
@@ -437,44 +437,44 @@ class MutableAttrInstanceState(InstanceState):
                     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
@@ -485,19 +485,19 @@ class MutableAttrInstanceState(InstanceState):
     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
@@ -509,13 +509,13 @@ class MutableAttrInstanceState(InstanceState):
                 except AssertionError:
                     pass
             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
@@ -523,7 +523,7 @@ class MutableAttrInstanceState(InstanceState):
 
         # re-establishes identity attributes from the key
         self.manager.dispatch.resurrect(self)
-        
+
         return obj
 
 class PendingCollection(object):
index d62bf37710304f5a2d9f141b30f915e63e27949c..7d3e563f41b6565939c806943d0cf152acc308dd 100644 (file)
@@ -32,15 +32,15 @@ def _register_attribute(strategy, mapper, useobject,
         proxy_property=None, 
         active_history=False,
         impl_class=None, 
-        **kw        
+        **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)
 
@@ -50,10 +50,10 @@ def _register_attribute(strategy, mapper, useobject,
                                 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)
@@ -63,10 +63,10 @@ def _register_attribute(strategy, mapper, useobject,
                                 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, 
@@ -85,16 +85,16 @@ def _register_attribute(strategy, mapper, useobject,
                 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
@@ -111,24 +111,24 @@ class UninstrumentedColumnLoader(LoaderStrategy):
 
 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  
+                            self.columns[0].primary_key
 
         _register_attribute(self, mapper, useobject=False,
             compare_function=coltype.compare_values,
@@ -136,7 +136,7 @@ class ColumnLoader(LoaderStrategy):
             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
@@ -189,7 +189,7 @@ class DeferredColumnLoader(LoaderStrategy):
 
     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,
@@ -207,17 +207,17 @@ class DeferredColumnLoader(LoaderStrategy):
             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 
@@ -244,7 +244,7 @@ class DeferredColumnLoader(LoaderStrategy):
         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):
@@ -253,7 +253,7 @@ class LoadDeferredColumns(object):
     def __init__(self, state, key):
         self.state = state
         self.key = key
-    
+
     def __call__(self, passive=False):
         state, key = self.state, self.key
 
@@ -264,7 +264,7 @@ class LoadDeferredColumns(object):
 
 class DeferredOption(StrategizedOption):
     propagate_to_loaders = True
-    
+
     def __init__(self, key, defer=False):
         super(DeferredOption, self).__init__(key)
         self.defer = defer
@@ -280,7 +280,7 @@ class UndeferGroupOption(MapperOption):
 
     def __init__(self, group):
         self.group = group
-        
+
     def process_query(self, query):
         query._attributes[('undefer', self.group)] = True
 
@@ -311,7 +311,7 @@ class NoLoader(AbstractRelationshipLoader):
         return new_execute, None, None
 
 log.class_logger(NoLoader)
-        
+
 class LazyLoader(AbstractRelationshipLoader):
     """Strategize a relationship() that loads when first accessed."""
 
@@ -320,7 +320,7 @@ class LazyLoader(AbstractRelationshipLoader):
         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
@@ -332,19 +332,19 @@ class LazyLoader(AbstractRelationshipLoader):
                             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 
@@ -372,7 +372,7 @@ class LazyLoader(AbstractRelationshipLoader):
             return self._lazy_none_clause(
                                         reverse_direction, 
                                         adapt_source=adapt_source)
-            
+
         if not reverse_direction:
             criterion, bind_to_col, rev = \
                                             self.__lazywhere, \
@@ -391,10 +391,10 @@ class LazyLoader(AbstractRelationshipLoader):
 
         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):
@@ -407,8 +407,8 @@ class LazyLoader(AbstractRelationshipLoader):
                 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()).\
@@ -420,7 +420,7 @@ class LazyLoader(AbstractRelationshipLoader):
         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 = \
@@ -438,18 +438,18 @@ class LazyLoader(AbstractRelationshipLoader):
         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 and 
                 not self.use_get
@@ -458,7 +458,7 @@ class LazyLoader(AbstractRelationshipLoader):
                 pending
             ):
             return attributes.PASSIVE_NO_RESULT
-            
+
         session = sessionlib._state_session(state)
         if not session:
             raise orm_exc.DetachedInstanceError(
@@ -474,7 +474,7 @@ class LazyLoader(AbstractRelationshipLoader):
                 get_attr = instance_mapper._get_committed_state_attr_by_column
             else:
                 get_attr = instance_mapper._get_state_attr_by_column
-            
+
             dict_ = state.dict
             ident = [
                 get_attr(
@@ -486,23 +486,23 @@ class LazyLoader(AbstractRelationshipLoader):
             ]
             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:
                 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,))
 
@@ -524,12 +524,12 @@ class LazyLoader(AbstractRelationshipLoader):
                 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()
@@ -543,7 +543,7 @@ class LazyLoader(AbstractRelationshipLoader):
                         "Multiple rows returned with "
                         "uselist=False for lazily-loaded attribute '%s' " 
                         % prop)
-                    
+
                 return result[0]
             else:
                 return None
@@ -568,14 +568,14 @@ class LazyLoader(AbstractRelationshipLoader):
                 # this class - reset its
                 # per-instance attribute state, so that the class-level 
                 # lazy loader is
-                # executed when next referenced on this instance.  
+                # 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()
@@ -592,7 +592,7 @@ class LazyLoader(AbstractRelationshipLoader):
                 _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]:
@@ -602,48 +602,48 @@ class LazyLoader(AbstractRelationshipLoader):
                     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=False):
         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):
@@ -652,29 +652,29 @@ class ImmediateLoader(AbstractRelationshipLoader):
     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), ())
@@ -689,13 +689,13 @@ class SubqueryLoader(AbstractRelationshipLoader):
             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 = \
@@ -705,7 +705,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
                                     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
@@ -728,11 +728,11 @@ class SubqueryLoader(AbstractRelationshipLoader):
         # 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,
@@ -760,25 +760,25 @@ class SubqueryLoader(AbstractRelationshipLoader):
         ]
         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:
@@ -804,11 +804,11 @@ class SubqueryLoader(AbstractRelationshipLoader):
                                     )
                                 )
             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)
@@ -819,7 +819,7 @@ class SubqueryLoader(AbstractRelationshipLoader):
                     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:
@@ -827,30 +827,30 @@ class SubqueryLoader(AbstractRelationshipLoader):
                         "'%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(
@@ -870,11 +870,11 @@ class SubqueryLoader(AbstractRelationshipLoader):
                         "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)
@@ -882,7 +882,7 @@ 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
@@ -890,27 +890,27 @@ class EagerLoader(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,
                                 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[
@@ -920,9 +920,9 @@ class EagerLoader(AbstractRelationshipLoader):
                 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 
@@ -950,7 +950,7 @@ class EagerLoader(AbstractRelationshipLoader):
                 # 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, 
@@ -961,10 +961,10 @@ class EagerLoader(AbstractRelationshipLoader):
             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, 
@@ -975,22 +975,22 @@ class EagerLoader(AbstractRelationshipLoader):
                 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 \
@@ -1024,7 +1024,7 @@ class EagerLoader(AbstractRelationshipLoader):
                                 ), 
                                 self.key, self.parent_property
                             )
-                
+
             if onclause is self.parent_property:
                 # TODO: this is a temporary hack to 
                 # account for polymorphic eager loads where
@@ -1051,7 +1051,7 @@ class EagerLoader(AbstractRelationshipLoader):
             # 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.  
+            # by the Query propagates those columns outward.
             # This has the effect 
             # of "undefering" those columns.
             for col in sql_util.find_columns(
@@ -1060,7 +1060,7 @@ class EagerLoader(AbstractRelationshipLoader):
                     if adapter:
                         col = adapter.columns[col]
                     context.primary_columns.append(col)
-        
+
         if self.parent_property.order_by:
             context.eager_order_by += \
                             eagerjoin._target_adapter.\
@@ -1070,7 +1070,7 @@ class EagerLoader(AbstractRelationshipLoader):
                                     )
                                 )
 
-        
+
     def _create_eager_adapter(self, context, row, adapter, path, reduced_path):
         if ("user_defined_eager_row_processor", reduced_path) in \
                                                     context.attributes:
@@ -1107,13 +1107,13 @@ class EagerLoader(AbstractRelationshipLoader):
 
         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(
@@ -1121,7 +1121,7 @@ class EagerLoader(AbstractRelationshipLoader):
                                 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
@@ -1184,11 +1184,11 @@ class EagerLazyOption(StrategizedOption):
         self.chained = chained
         self.propagate_to_loaders = propagate_to_loaders
         self.strategy_cls = factory(lazy)
-    
+
     @property
     def is_eager(self):
         return self.lazy in (False, 'joined', 'subquery')
-    
+
     @property
     def is_chained(self):
         return self.is_eager and self.chained
@@ -1209,16 +1209,16 @@ def factory(identifier):
         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 is_chained(self):
         return self.chained
 
@@ -1228,9 +1228,9 @@ class EagerJoinOption(PropertyOption):
                 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):
         super(LoadEagerFromAliasOption, self).__init__(key)
         if alias is not None:
@@ -1270,13 +1270,13 @@ def single_parent_validator(desc, prop):
                     (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)
-    
+
index 30d56d168c5ee4066f0cee4c85450a7c39c9ff98..bc250b226ab3a0c3adf5b8f910fe3ee3246147b9 100644 (file)
@@ -14,7 +14,7 @@ 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
@@ -29,7 +29,7 @@ def populate(source, source_mapper, dest, dest_mapper,
             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)
-        
+
         # techically 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
@@ -75,7 +75,7 @@ def populate_dict(source, source_mapper, dict_, synchronize_pairs):
 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:
index e6b1c0483af309207090dbd437f33a4226e08fe8..f1c5fcfc680491c391a3612d351bce491c0e2ed0 100644 (file)
@@ -21,10 +21,10 @@ 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
@@ -38,7 +38,7 @@ def track_cascade_events(descriptor, prop):
                 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:
@@ -65,15 +65,15 @@ def track_cascade_events(descriptor, prop):
                     (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)
@@ -86,45 +86,45 @@ class UOWTransaction(object):
         # 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)
@@ -132,23 +132,23 @@ class UOWTransaction(object):
     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=True):
         """facade to attributes.get_state_history(), including caching of results."""
 
@@ -157,7 +157,7 @@ class UOWTransaction(object):
         # 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 
@@ -180,17 +180,17 @@ class UOWTransaction(object):
             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):
@@ -203,56 +203,56 @@ class UOWTransaction(object):
 
         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
@@ -269,7 +269,7 @@ class UOWTransaction(object):
         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
@@ -294,7 +294,7 @@ class UOWTransaction(object):
                     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
                     ]
@@ -302,13 +302,13 @@ class UOWTransaction(object):
 
     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(
@@ -322,14 +322,14 @@ class UOWTransaction(object):
                                     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:
@@ -348,18 +348,18 @@ class IterateMappersMixin(object):
             )
         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]
@@ -375,7 +375,7 @@ class Preprocess(IterateMappersMixin):
         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.\
@@ -391,7 +391,7 @@ class Preprocess(IterateMappersMixin):
 
 class PostSortRec(object):
     disabled = False
-    
+
     def __new__(cls, uow, *args):
         key = (cls, ) + args
         if key in uow.postsort_actions:
@@ -401,10 +401,10 @@ class PostSortRec(object):
                                     ret = \
                                     object.__new__(cls)
             return ret
-    
+
     def execute_aggregate(self, uow, recs):
         self.execute(uow)
-        
+
     def __repr__(self):
         return "%s(%s)" % (
             self.__class__.__name__,
@@ -417,7 +417,7 @@ class ProcessAll(IterateMappersMixin, PostSortRec):
         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:
@@ -454,20 +454,20 @@ class IssuePostUpdate(PostSortRec):
     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(
@@ -475,11 +475,11 @@ class SaveUpdateAll(PostSortRec):
                             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
@@ -498,7 +498,7 @@ class DeleteAll(PostSortRec):
                             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)
@@ -531,12 +531,12 @@ class ProcessState(PostSortRec):
             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
@@ -559,7 +559,7 @@ 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
index a69670c295bebcf781d41c4ec875c8ca6393422b..7866aab2b5a6b0ca268e0b4091d5509c453c53f8 100644 (file)
@@ -28,7 +28,7 @@ class CascadeOptions(dict):
             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
@@ -38,7 +38,7 @@ class CascadeOptions(dict):
         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.")
@@ -61,10 +61,10 @@ def _validator_events(desc, key, validator):
 
     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'):
     """Create a ``UNION`` statement used by a polymorphic mapper.
 
@@ -197,8 +197,8 @@ class AliasedClass(object):
     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.   
-    
+    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
@@ -264,7 +264,7 @@ class AliasedClass(object):
                 break
         else:
             raise AttributeError(key)
-        
+
         if isinstance(attr, attributes.QueryableAttribute):
             return self.__adapt_prop(attr, key)
         elif hasattr(attr, 'func_code'):
@@ -391,19 +391,19 @@ 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`.
 
@@ -411,7 +411,7 @@ def with_parent(instance, prop):
       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)
@@ -440,24 +440,24 @@ def _entity_info(entity, compile=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.
 
@@ -516,7 +516,7 @@ def class_mapper(class_, compile=True):
     Raises UnmappedClassError if no mapping is configured.
 
     """
-    
+
     try:
         class_manager = attributes.manager_of_class(class_)
         mapper = class_manager.mapper
@@ -542,7 +542,7 @@ def _class_to_mapper(class_or_mapper, compile=True):
         mapper = class_or_mapper
     else:
         raise exc.UnmappedClassError(class_or_mapper)
-        
+
     if compile and mapperlib.module._new_mappers:
         mapperlib.configure_mappers()
     return mapper
@@ -581,7 +581,7 @@ def state_class_str(state):
         return "None"
     else:
         return '<%s>' % (state.class_.__name__, )
-    
+
 def attribute_str(instance, attribute):
     return instance_str(instance) + "." + attribute
 
index 7c88d663a8caee44f6258aad9af6f2b450f09c2c..23a4c6946fa153533d65187e12e02a69aec4e4eb 100644 (file)
@@ -61,7 +61,7 @@ class Pool(log.Identified):
     """Abstract base class for connection pools."""
 
     _no_finalize = False
-    
+
     def __init__(self, 
                     creator, recycle=-1, echo=None, 
                     use_threadlocal=False,
@@ -106,13 +106,13 @@ class Pool(log.Identified):
           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
@@ -125,7 +125,7 @@ class Pool(log.Identified):
             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
@@ -146,42 +146,42 @@ class Pool(log.Identified):
                 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()
@@ -193,18 +193,18 @@ class Pool(log.Identified):
         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()
@@ -222,10 +222,10 @@ class Pool(log.Identified):
 
     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:
@@ -236,12 +236,12 @@ class Pool(log.Identified):
 
     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):
@@ -321,10 +321,10 @@ class _ConnectionRecord(object):
 
 def _finalize_fairy(connection, connection_record, pool, ref, echo):
     _refs.discard(connection_record)
-    
+
     if pool._no_finalize:
         return
-        
+
     if ref is not None and \
                 connection_record.fairy is not ref:
         return
@@ -341,7 +341,7 @@ def _finalize_fairy(connection, connection_record, pool, ref, echo):
                 connection_record.invalidate(e=e)
             if isinstance(e, (SystemExit, KeyboardInterrupt)):
                 raise
-                
+
     if connection_record is not None:
         connection_record.fairy = None
         if echo:
@@ -360,7 +360,7 @@ class _ConnectionFairy(object):
     __slots__ = '_pool', '__counter', 'connection', \
                 '_connection_record', '__weakref__', \
                 '_detached_info', '_echo'
-    
+
     def __init__(self, pool):
         self._pool = pool
         self.__counter = 0
@@ -501,7 +501,7 @@ class SingletonThreadPool(Pool):
         at once.  Defaults to five.
 
     :class:`.SingletonThreadPool` is used by the SQLite dialect
-    automatically when a memory-based database is used.  
+    automatically when a memory-based database is used.
     See :ref:`sqlite_toplevel`.
 
     """
@@ -535,9 +535,9 @@ class SingletonThreadPool(Pool):
                 # 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:
             self._all_conns.pop()
@@ -565,10 +565,10 @@ class SingletonThreadPool(Pool):
 
 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,
@@ -741,9 +741,9 @@ class NullPool(Pool):
     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).   
+    when a file-based database is used (as of SQLAlchemy 0.7).
     See :ref:`sqlite_toplevel`.
 
     """
@@ -788,7 +788,7 @@ class StaticPool(Pool):
     @memoized_property
     def connection(self):
         return _ConnectionRecord(self)
-        
+
     def status(self):
         return "StaticPool"
 
@@ -826,12 +826,12 @@ class AssertionPool(Pool):
 
     """
     _no_finalize = True
-    
+
     def __init__(self, *args, **kw):
         self._conn = None
         self._checked_out = False
         Pool.__init__(self, *args, **kw)
-        
+
     def status(self):
         return "AssertionPool"
 
@@ -851,14 +851,14 @@ class AssertionPool(Pool):
         return AssertionPool(self._creator, echo=self.echo, 
                             logging_name=self._orig_logging_name,
                             _dispatch=self.dispatch)
-        
+
     def _do_get(self):
         if self._checked_out:
             raise AssertionError("connection is already checked out")
-            
+
         if not self._conn:
             self._conn = self._create_connection()
-        
+
         self._checked_out = True
         return self._conn
 
@@ -880,7 +880,7 @@ class _DBProxy(object):
           a Pool class, defaulting to QueuePool
 
         Other parameters are sent to the Pool object's constructor.
-        
+
         """
 
         self.module = module
@@ -888,7 +888,7 @@ class _DBProxy(object):
         self.poolclass = poolclass
         self.pools = {}
         self._create_pool_mutex = threading.Lock()
-        
+
     def close(self):
         for key in self.pools.keys():
             del self.pools[key]
@@ -915,7 +915,7 @@ class _DBProxy(object):
                     return self.pools[key]
             finally:
                 self._create_pool_mutex.release()
-                
+
     def connect(self, *args, **kw):
         """Activate a connection to the database.
 
@@ -927,7 +927,7 @@ class _DBProxy(object):
 
         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()
index 422991ec0a8e3a6494261c6c23c6e307f13ab46a..cb5f00bdefa72c9400ecdc5b95363c67b3ee1e2e 100644 (file)
@@ -46,7 +46,7 @@ try:
             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. 
index 2156bc5467524bdeee711fa61ff11229ede2f9a6..eb03fae98f8f27163378dca2c478e995dad9007d 100644 (file)
@@ -83,12 +83,12 @@ def _get_table_key(name, schema):
     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))
@@ -97,7 +97,7 @@ class Table(SchemaItem, expression.TableClause):
     The Table object constructs a unique instance of itself based on its
     name within the given MetaData object.   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
@@ -123,7 +123,7 @@ class Table(SchemaItem, expression.TableClause):
         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.
@@ -174,7 +174,7 @@ class Table(SchemaItem, expression.TableClause):
         :class:`Table` are overwritten.
 
     """
-    
+
     __visit_name__ = 'table'
 
     dispatch = event.dispatcher(events.DDLEvents)
@@ -183,12 +183,12 @@ class Table(SchemaItem, expression.TableClause):
         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)
         useexisting = kw.pop('useexisting', False)
         mustexist = kw.pop('mustexist', False)
@@ -206,7 +206,7 @@ class Table(SchemaItem, expression.TableClause):
             if mustexist:
                 raise exc.InvalidRequestError(
                     "Table '%s' not defined" % (key))
-            table = object.__new__(cls)                    
+            table = object.__new__(cls)
             metadata._add_table(name, schema, table)
             try:
                 table._init(name, metadata, *args, **kw)
@@ -214,12 +214,12 @@ class Table(SchemaItem, expression.TableClause):
             except:
                 metadata._remove_table(name, schema)
                 raise
-                
+
     def __init__(self, *args, **kw):
         # __init__ is overridden to prevent __new__ from 
         # calling the superclass constructor.
         pass
-        
+
     def _init(self, name, metadata, *args, **kwargs):
         super(Table, self).__init__(name)
         self.metadata = metadata
@@ -309,7 +309,7 @@ class Table(SchemaItem, expression.TableClause):
 
     def _init_collections(self):
         pass
-        
+
     def _set_primary_key(self, pk):
         if self.primary_key in self.constraints:
             self.constraints.remove(self.primary_key)
@@ -350,18 +350,18 @@ class Table(SchemaItem, expression.TableClause):
 
     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 ``Column`` to this ``Table``."""
 
@@ -374,14 +374,14 @@ class Table(SchemaItem, expression.TableClause):
 
     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):
@@ -428,14 +428,14 @@ class Table(SchemaItem, expression.TableClause):
         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()
@@ -445,7 +445,7 @@ class Table(SchemaItem, expression.TableClause):
 
             # create the same Table object for the plain metadata
             users_table_2 = users_table.tometadata(meta2)
-        
+
         """
 
         if schema is RETAIN_SCHEMA:
@@ -481,38 +481,38 @@ 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.
 
@@ -541,21 +541,21 @@ class Column(SchemaItem, expression.ColumnClause):
           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,
@@ -564,7 +564,7 @@ class Column(SchemaItem, expression.ColumnClause):
             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
@@ -579,14 +579,14 @@ class Column(SchemaItem, expression.ColumnClause):
             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
@@ -614,7 +614,7 @@ class Column(SchemaItem, expression.ColumnClause):
             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
@@ -640,7 +640,7 @@ class Column(SchemaItem, expression.ColumnClause):
 
             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
@@ -682,7 +682,7 @@ class Column(SchemaItem, expression.ColumnClause):
                 name = args.pop(0)
         if args:
             coltype = args[0]
-            
+
             if (isinstance(coltype, types.TypeEngine) or
                 (isinstance(coltype, type) and
                  issubclass(coltype, types.TypeEngine))):
@@ -690,9 +690,9 @@ class Column(SchemaItem, expression.ColumnClause):
                     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)
@@ -716,7 +716,7 @@ class Column(SchemaItem, expression.ColumnClause):
         # otherwise, add DDL-related events
         elif isinstance(self.type, types.SchemaType):
             self.type._set_parent(self)
-            
+
         if self.default is not None:
             if isinstance(self.default, (ColumnDefault, Sequence)):
                 args.append(self.default)
@@ -728,13 +728,13 @@ class Column(SchemaItem, expression.ColumnClause):
                 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_default)
@@ -750,7 +750,7 @@ class Column(SchemaItem, expression.ColumnClause):
 
         if 'info' in kwargs:
             self.info = kwargs.pop('info')
-            
+
         if kwargs:
             raise exc.ArgumentError(
                 "Unknown arguments passed to Column: " + repr(kwargs.keys()))
@@ -822,7 +822,7 @@ class Column(SchemaItem, expression.ColumnClause):
                     # 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:
@@ -854,25 +854,25 @@ class Column(SchemaItem, expression.ColumnClause):
         for fn in self._table_events:
             fn(table, self)
         del self._table_events
-    
+
     def _on_table_attach(self, fn):
         if self.table is not None:
             fn(self.table, self)
         else:
             self._table_events.add(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, 
@@ -893,7 +893,7 @@ class Column(SchemaItem, expression.ColumnClause):
         if hasattr(self, '_table_events'):
             c._table_events = list(self._table_events)
         return c
-        
+
     def _make_proxy(self, selectable, name=None):
         """Create a *proxy* for this column.
 
@@ -901,7 +901,7 @@ class Column(SchemaItem, expression.ColumnClause):
         (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:
@@ -938,11 +938,11 @@ class ForeignKey(SchemaItem):
 
     ``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`
@@ -953,18 +953,18 @@ class ForeignKey(SchemaItem):
     ``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`.
 
@@ -976,8 +976,8 @@ class ForeignKey(SchemaItem):
                     onupdate=None, ondelete=None, deferrable=None,
                     initially=None, link_to_name=False):
         """
-        Construct a column-level FOREIGN KEY.  
-        
+        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.
@@ -1005,28 +1005,28 @@ class ForeignKey(SchemaItem):
 
         :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
@@ -1040,20 +1040,20 @@ class ForeignKey(SchemaItem):
 
     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.
-          
+
         """
-        
+
         return ForeignKey(
                 self._get_colspec(schema=schema),
                 use_alter=self.use_alter,
@@ -1067,10 +1067,10 @@ class ForeignKey(SchemaItem):
 
     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 + \
@@ -1081,14 +1081,14 @@ class ForeignKey(SchemaItem):
             _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):
@@ -1105,7 +1105,7 @@ class ForeignKey(SchemaItem):
     @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
@@ -1114,7 +1114,7 @@ class ForeignKey(SchemaItem):
         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
@@ -1165,7 +1165,7 @@ class ForeignKey(SchemaItem):
                     "foreign key to target column '%s'" % (self.parent, tname, colname))
             table = Table(tname, parenttable.metadata,
                           mustexist=True, schema=schema)
-                          
+
             _column = None
             if colname is None:
                 # colname is None in the case that ForeignKey argument
@@ -1208,7 +1208,7 @@ class ForeignKey(SchemaItem):
         self.parent = column
         self.parent.foreign_keys.add(self)
         self.parent._on_table_attach(self._set_table)
-    
+
     def _set_table(self, table, column):
         # standalone ForeignKey - create ForeignKeyConstraint
         # on the hosting Table when attached to the Table.
@@ -1221,14 +1221,14 @@ class ForeignKey(SchemaItem):
             self.constraint._elements[self.parent] = self
             self.constraint._set_parent(table)
         table.foreign_keys.add(self)
-        
+
 class DefaultGenerator(SchemaItem):
     """Base class for column *default* values."""
 
     __visit_name__ = 'default_generator'
 
     is_sequence = False
-    
+
     def __init__(self, for_update=False):
         self.for_update = for_update
 
@@ -1261,21 +1261,21 @@ class ColumnDefault(DefaultGenerator):
 
     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):
@@ -1286,21 +1286,21 @@ class ColumnDefault(DefaultGenerator):
         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."""
 
@@ -1319,7 +1319,7 @@ class ColumnDefault(DefaultGenerator):
             return lambda ctx: fn()
 
         positionals = len(argspec[0])
-        
+
         # Py3K compat - no unbound methods
         if inspect.ismethod(inspectable) or inspect.isclass(fn):
             positionals -= 1
@@ -1350,7 +1350,7 @@ class Sequence(DefaultGenerator):
     __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):
         super(Sequence, self).__init__(for_update=for_update)
@@ -1379,17 +1379,17 @@ class Sequence(DefaultGenerator):
     def _set_parent(self, column):
         super(Sequence, self)._set_parent(column)
         column._on_table_attach(self._set_table)
-    
+
     def _set_table(self, table, column):
         self.metadata = table.metadata
-        
+
     @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."""
 
@@ -1407,18 +1407,18 @@ class Sequence(DefaultGenerator):
 
 class FetchedValue(object):
     """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.
-    
+
     """
 
     def __init__(self, for_update=False):
@@ -1437,24 +1437,24 @@ class FetchedValue(object):
 
 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"))
-    
+
     """
 
     def __init__(self, arg, for_update=False):
@@ -1470,7 +1470,7 @@ class DefaultClause(FetchedValue):
 
 class PassiveDefault(DefaultClause):
     """A DDL-specified DEFAULT column value.
-    
+
     .. deprecated:: 0.6 :class:`.PassiveDefault` is deprecated. 
         Use :class:`.DefaultClause`.
     """
@@ -1500,7 +1500,7 @@ class Constraint(SchemaItem):
         :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
@@ -1517,7 +1517,7 @@ class Constraint(SchemaItem):
 
           _create_rule is used by some types to create constraints.
           Currently, its call signature is subject to change at any time.
-          
+
         """
 
         self.name = name
@@ -1545,7 +1545,7 @@ class Constraint(SchemaItem):
 
 class ColumnCollectionConstraint(Constraint):
     """A constraint that proxies a ColumnCollection."""
-    
+
     def __init__(self, *columns, **kw):
         """
         :param \*columns:
@@ -1561,7 +1561,7 @@ class ColumnCollectionConstraint(Constraint):
         :param initially:
           Optional string.  If set, emit INITIALLY <value> when issuing DDL
           for this constraint.
-        
+
         """
         super(ColumnCollectionConstraint, self).__init__(**kw)
         self.columns = expression.ColumnCollection()
@@ -1571,7 +1571,7 @@ class ColumnCollectionConstraint(Constraint):
                 isinstance(self._pending_colargs[0], Column) and \
                 self._pending_colargs[0].table is not None:
             self._set_parent(self._pending_colargs[0].table)
-        
+
     def _set_parent(self, table):
         super(ColumnCollectionConstraint, self)._set_parent(table)
         for col in self._pending_colargs:
@@ -1613,7 +1613,7 @@ class CheckConstraint(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.
 
@@ -1624,7 +1624,7 @@ class CheckConstraint(Constraint):
         :param initially:
           Optional string.  If set, emit INITIALLY <value> when issuing DDL
           for this constraint.
-          
+
         """
 
         super(CheckConstraint, self).\
@@ -1632,7 +1632,7 @@ class CheckConstraint(Constraint):
         self.sqltext = expression._literal_as_text(sqltext)
         if table is not None:
             self._set_parent(table)
-            
+
     def __visit_name__(self):
         if isinstance(self.parent, Table):
             return "check_constraint"
@@ -1650,9 +1650,9 @@ class ForeignKeyConstraint(Constraint):
     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'
 
@@ -1698,7 +1698,7 @@ class ForeignKeyConstraint(Constraint):
           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)
@@ -1711,7 +1711,7 @@ class ForeignKeyConstraint(Constraint):
         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 
@@ -1729,15 +1729,15 @@ class ForeignKeyConstraint(Constraint):
 
         if table is not None:
             self._set_parent(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():
@@ -1746,16 +1746,16 @@ class ForeignKeyConstraint(Constraint):
             if isinstance(col, basestring):
                 col = table.c[col]
             fk._set_parent(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):
         return ForeignKeyConstraint(
                     [x.parent.name for x in self._elements.values()], 
@@ -1823,7 +1823,7 @@ class Index(SchemaItem):
 
         :param \**kw:
             Other keyword arguments may be interpreted by specific dialects.
-        
+
         """
 
         self.name = name
@@ -1851,7 +1851,7 @@ class Index(SchemaItem):
     @property
     def bind(self):
         """Return the connectable associated with this Index."""
-        
+
         return self.table.bind
 
     def create(self, bind=None):
@@ -1943,7 +1943,7 @@ class MetaData(SchemaItem):
         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)
@@ -1951,7 +1951,7 @@ class MetaData(SchemaItem):
             self._schemas = set([t.schema 
                                 for t in self.tables.values() 
                                 if t.schema is not None])
-        
+
     def __getstate__(self):
         return {'tables': self.tables}
 
@@ -1970,7 +1970,7 @@ class MetaData(SchemaItem):
         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
 
@@ -1989,10 +1989,10 @@ class MetaData(SchemaItem):
 
         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
@@ -2001,7 +2001,7 @@ class MetaData(SchemaItem):
         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.
 
@@ -2018,10 +2018,10 @@ class MetaData(SchemaItem):
 
         :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.
@@ -2054,7 +2054,7 @@ class MetaData(SchemaItem):
             available.update(
                 bind.dialect.get_view_names(conn or bind, schema)
             )
-            
+
         current = set(self.tables.iterkeys())
 
         if only is None:
@@ -2083,7 +2083,7 @@ class MetaData(SchemaItem):
         """
         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):
@@ -2104,7 +2104,7 @@ class MetaData(SchemaItem):
         :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)
@@ -2206,16 +2206,16 @@ class SchemaVisitor(visitors.ClauseVisitor):
 
 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',
@@ -2223,17 +2223,17 @@ class DDLElement(expression.Executable, expression.ClauseElement):
         )
 
     See also:
-    
+
         :class:`.DDL`
-        
+
         :class:`.DDLEvents`
-    
+
         :ref:`event_toplevel`
 
         :ref:`schema_ddl_sequences`
-        
+
     """
-    
+
     _execution_options = expression.Executable.\
                             _execution_options.union({'autocommit':True})
 
@@ -2241,7 +2241,7 @@ class DDLElement(expression.Executable, expression.ClauseElement):
     on = None
     dialect = None
     callable_ = None
-    
+
     def execute(self, bind=None, target=None):
         """Execute this DDL immediately.
 
@@ -2277,13 +2277,13 @@ class DDLElement(expression.Executable, expression.ClauseElement):
         ":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'
@@ -2300,14 +2300,14 @@ class DDLElement(expression.Executable, expression.ClauseElement):
         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
@@ -2320,15 +2320,15 @@ class DDLElement(expression.Executable, expression.ClauseElement):
     def execute_if(self, dialect=None, callable_=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::
@@ -2338,14 +2338,14 @@ class DDLElement(expression.Executable, expression.ClauseElement):
           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.
@@ -2353,20 +2353,20 @@ class DDLElement(expression.Executable, expression.ClauseElement):
             :bind:
               The :class:`.Connection` being used for DDL execution
 
-            :tables:  
+            :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.
-                    
+
         See also:
-        
+
             :class:`.DDLEvents`
-            
+
             :ref:`event_toplevel`
-            
+
         """
         self.dialect = dialect
         self.callable_ = callable_
@@ -2375,7 +2375,7 @@ class DDLElement(expression.Executable, expression.ClauseElement):
         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
@@ -2385,7 +2385,7 @@ class DDLElement(expression.Executable, expression.ClauseElement):
         if self.callable_ is not None and \
             not self.callable_(self, target, bind, **kw):
             return False
-            
+
         return True
 
     def _should_execute_deprecated(self, event, target, bind, **kw):
@@ -2397,10 +2397,10 @@ class DDLElement(expression.Executable, expression.ClauseElement):
             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))
 
@@ -2424,11 +2424,11 @@ class DDLElement(expression.Executable, expression.ClauseElement):
         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):
@@ -2441,9 +2441,9 @@ class DDL(DDLElement):
     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'))
 
@@ -2467,7 +2467,7 @@ class DDL(DDLElement):
     """
 
     __visit_name__ = "ddl"
-    
+
     def __init__(self, statement, on=None, context=None, bind=None):
         """Create a DDL statement.
 
@@ -2495,10 +2495,10 @@ class DDL(DDLElement):
 
           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.
@@ -2510,12 +2510,12 @@ class DDL(DDLElement):
             :connection:
               The ``Connection`` being used for DDL execution
 
-            :tables:  
+            :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.
 
@@ -2529,10 +2529,10 @@ class DDL(DDLElement):
 
 
         See also:
-        
+
             :class:`.DDLEvents`
             :mod:`sqlalchemy.event`
-          
+
         """
 
         if not isinstance(statement, basestring):
@@ -2575,9 +2575,9 @@ class _CreateDropBase(DDLElement):
     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)
@@ -2586,19 +2586,19 @@ class _CreateDropBase(DDLElement):
 
     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."""
 
@@ -2606,17 +2606,17 @@ class DropTable(_CreateDropBase):
 
 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):
@@ -2626,19 +2626,19 @@ class DropIndex(_CreateDropBase):
 
 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)
@@ -2659,7 +2659,7 @@ def _bind_or_error(schemaitem, msg=None):
             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 "\
index 07ef0f50aa2fbe4026b2d48af77b4b2fa35f6bd4..39d320edeb9cee5927b966af65d37950dc4392c5 100644 (file)
@@ -152,15 +152,15 @@ class _CompileLabel(visitors.Visitable):
 
     __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
@@ -176,28 +176,28 @@ class SQLCompiler(engine.Compiled):
     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.
@@ -256,7 +256,7 @@ class SQLCompiler(engine.Compiled):
         self.truncated_names = {}
         engine.Compiled.__init__(self, dialect, statement, **kwargs)
 
-        
+
 
     @util.memoized_property
     def _bind_processors(self):
@@ -267,14 +267,14 @@ class SQLCompiler(engine.Compiled):
                   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"""
 
@@ -353,25 +353,25 @@ class SQLCompiler(engine.Compiled):
             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
@@ -385,7 +385,7 @@ class SQLCompiler(engine.Compiled):
             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
@@ -407,7 +407,7 @@ class SQLCompiler(engine.Compiled):
 
     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():
@@ -486,14 +486,14 @@ class SQLCompiler(engine.Compiled):
         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:
@@ -523,7 +523,7 @@ class SQLCompiler(engine.Compiled):
             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) + 
@@ -550,7 +550,7 @@ class SQLCompiler(engine.Compiled):
             + (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)' % (
@@ -559,7 +559,7 @@ class SQLCompiler(engine.Compiled):
             + (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)' % (
@@ -568,7 +568,7 @@ class SQLCompiler(engine.Compiled):
             + (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)
@@ -578,7 +578,7 @@ class SQLCompiler(engine.Compiled):
                 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 \
@@ -589,7 +589,7 @@ class SQLCompiler(engine.Compiled):
                                         "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]
@@ -610,26 +610,26 @@ class SQLCompiler(engine.Compiled):
                         "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("'", "''")
@@ -643,7 +643,7 @@ class SQLCompiler(engine.Compiled):
         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]
@@ -672,10 +672,10 @@ class SQLCompiler(engine.Compiled):
             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)
@@ -705,12 +705,12 @@ class SQLCompiler(engine.Compiled):
                                 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)
@@ -742,16 +742,16 @@ class SQLCompiler(engine.Compiled):
 
     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)
@@ -782,7 +782,7 @@ class SQLCompiler(engine.Compiled):
             ]
             if c is not None
         ]
-        
+
         text = "SELECT "  # we're off to a good start !
 
         if select._hints:
@@ -798,7 +798,7 @@ class SQLCompiler(engine.Compiled):
             hint_text = self.get_select_hint_text(byfrom)
             if hint_text:
                 text += hint_text + " "
-                
+
         if select._prefixes:
             text += " ".join(
                             x._compiler_dispatch(self, **kwargs) 
@@ -808,7 +808,7 @@ class SQLCompiler(engine.Compiled):
 
         if froms:
             text += " \nFROM "
-            
+
             if select._hints:
                 text += ', '.join([f._compiler_dispatch(self, 
                                     asfrom=True, fromhints=byfrom, 
@@ -854,7 +854,7 @@ class SQLCompiler(engine.Compiled):
     def get_select_precolumns(self, select):
         """Called when building a ``SELECT`` statement, position is just
         before column list.
-        
+
         """
         return select._distinct and "DISTINCT " or ""
 
@@ -924,15 +924,15 @@ class SQLCompiler(engine.Compiled):
 
         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])
@@ -941,7 +941,7 @@ class SQLCompiler(engine.Compiled):
             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
 
@@ -950,12 +950,12 @@ class SQLCompiler(engine.Compiled):
         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])})
 
@@ -963,7 +963,7 @@ class SQLCompiler(engine.Compiled):
         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) + 
@@ -976,14 +976,14 @@ class SQLCompiler(engine.Compiled):
             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
@@ -1001,10 +1001,10 @@ class SQLCompiler(engine.Compiled):
                     "with insert() or update() (for example, 'b_%s')."
                     % (col.key, col.key)
                 )
-            
+
         self.binds[col.key] = bindparam
         return self.bindparam_string(self._truncate_bindparam(bindparam))
-        
+
     def _get_colparams(self, stmt):
         """create a set of tuples representing column/string pairs for use
         in an INSERT or UPDATE statement.
@@ -1030,7 +1030,7 @@ class SQLCompiler(engine.Compiled):
                     ]
 
         required = object()
-        
+
         # if we have statement parameters - set defaults in the
         # compiled params
         if self.column_keys is None:
@@ -1047,17 +1047,17 @@ class SQLCompiler(engine.Compiled):
 
         # 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.
@@ -1071,7 +1071,7 @@ class SQLCompiler(engine.Compiled):
                     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 \
@@ -1080,7 +1080,7 @@ class SQLCompiler(engine.Compiled):
                         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:
@@ -1115,7 +1115,7 @@ class SQLCompiler(engine.Compiled):
                                 (c, self._create_crud_bind_param(c, None))
                             )
                             self.prefetch.append(c)
-                
+
                 elif c.default is not None:
                     if c.default.is_sequence:
                         proc = self.process(c.default)
@@ -1127,7 +1127,7 @@ class SQLCompiler(engine.Compiled):
                         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)
@@ -1139,7 +1139,7 @@ class SQLCompiler(engine.Compiled):
                 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:
@@ -1167,14 +1167,14 @@ class SQLCompiler(engine.Compiled):
             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
@@ -1192,18 +1192,18 @@ class SQLCompiler(engine.Compiled):
 
 
 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
@@ -1220,7 +1220,7 @@ class DDLCompiler(engine.Compiled):
             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):
@@ -1259,16 +1259,16 @@ class DDLCompiler(engine.Compiled):
         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.constraints 
                                 if c is not table.primary_key])
-        
+
         return ", \n\t".join(p for p in
                         (self.process(constraint) 
                         for constraint in constraints 
@@ -1280,7 +1280,7 @@ class DDLCompiler(engine.Compiled):
                             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)
 
@@ -1302,7 +1302,7 @@ class DDLCompiler(engine.Compiled):
         preparer = self.preparer
         text = "CREATE "
         if index.unique:
-            text += "UNIQUE "   
+            text += "UNIQUE "
         text += "INDEX %s ON %s (%s)" \
                     % (preparer.quote(self._index_identifier(index.name), 
                         index.quote),
@@ -1332,7 +1332,7 @@ class DDLCompiler(engine.Compiled):
         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)
@@ -1344,7 +1344,7 @@ class DDLCompiler(engine.Compiled):
             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)
@@ -1417,7 +1417,7 @@ class DDLCompiler(engine.Compiled):
 
     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):
@@ -1438,7 +1438,7 @@ class DDLCompiler(engine.Compiled):
         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:
@@ -1449,15 +1449,15 @@ class DDLCompiler(engine.Compiled):
         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"
 
@@ -1474,7 +1474,7 @@ class GenericTypeCompiler(engine.TypeCompiler):
 
     def visit_DECIMAL(self, type_):
         return "DECIMAL"
-        
+
     def visit_INTEGER(self, type_):
         return "INTEGER"
 
@@ -1516,46 +1516,46 @@ class GenericTypeCompiler(engine.TypeCompiler):
 
     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_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_)
 
@@ -1564,19 +1564,19 @@ class GenericTypeCompiler(engine.TypeCompiler):
 
     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."""
 
@@ -1609,7 +1609,7 @@ class IdentifierPreparer(object):
         self.escape_to_quote = self.escape_quote * 2
         self.omit_schema = omit_schema
         self._strings = {}
-        
+
     def _escape_identifier(self, value):
         """Escape an identifier.
 
@@ -1689,7 +1689,7 @@ class IdentifierPreparer(object):
 
     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."""
 
@@ -1754,7 +1754,7 @@ class IdentifierPreparer(object):
               'final': final,
               'escaped': escaped_final })
         return r
-        
+
     def unformat_identifiers(self, identifiers):
         """Unpack 'schema.table.column'-like strings into components."""
 
index c1312c85372dfeae11bc568692a7736b81fe85da..ede194f7ccfcf4920b78d29d2b8fd2fa6d95ddf7 100644 (file)
@@ -474,7 +474,7 @@ def case(whens, value=None, else_=None):
     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'",
@@ -482,7 +482,7 @@ def case(whens, value=None, else_=None):
             ], else_=literal_column("'lethan10'", String))
 
     """
-    
+
     return _Case(whens, value=value, else_=else_)
 
 def cast(clause, totype, **kwargs):
@@ -678,29 +678,29 @@ def literal(value, type_=None):
     return _BindParamClause(None, value, type_=type_, unique=True)
 
 def tuple_(*expr):
-    """Return a SQL tuple.   
-    
+    """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
 
@@ -709,25 +709,25 @@ def type_coerce(expr, type_):
                     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()
@@ -735,8 +735,8 @@ def type_coerce(expr, type_):
             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`.
@@ -826,14 +826,14 @@ def bindparam(key, value=None, type_=None, unique=False, required=False, callabl
           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
@@ -844,10 +844,10 @@ def bindparam(key, value=None, type_=None, unique=False, required=False, callabl
           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, 
@@ -873,65 +873,65 @@ def outparam(key, type_=None):
 
 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.   
+
+    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``, 
@@ -970,7 +970,7 @@ def text(text, bind=None, *args, **kwargs):
 def null():
     """Return a :class:`_Null` object, which compiles to ``NULL`` in a sql
     statement.
-    
+
     """
     return _Null()
 
@@ -1023,24 +1023,24 @@ def _escape_for_generated(x):
         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.
@@ -1072,7 +1072,7 @@ def _column_as_key(element):
     if hasattr(element, '__clause_element__'):
         element = element.__clause_element__()
     return element.key
-    
+
 def _literal_as_text(element):
     if hasattr(element, '__clause_element__'):
         return element.__clause_element__()
@@ -1088,7 +1088,7 @@ def _clause_element_as_expr(element):
         return element.__clause_element__()
     else:
         return element
-        
+
 def _literal_as_column(element):
     if isinstance(element, Visitable):
         return element
@@ -1133,7 +1133,7 @@ def _only_column_elements(element, name):
         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,
@@ -1159,14 +1159,14 @@ def _generative(fn, *args, **kw):
 
 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'
 
@@ -1174,7 +1174,7 @@ class ClauseElement(Visitable):
     supports_execution = False
     _from_objects = []
     _bind = None
-    
+
     def _clone(self):
         """Create a shallow copy of this ClauseElement.
 
@@ -1199,9 +1199,9 @@ class ClauseElement(Visitable):
     @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__.  
+        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.
 
@@ -1229,7 +1229,7 @@ class ClauseElement(Visitable):
         d = self.__dict__.copy()
         d.pop('_is_clone_of', None)
         return d
-    
+
     if util.jython:
         def __hash__(self):
             """Return a distinct hash code.
@@ -1240,18 +1240,18 @@ class ClauseElement(Visitable):
             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()
 
@@ -1299,7 +1299,7 @@ class ClauseElement(Visitable):
 
         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`)
@@ -1332,7 +1332,7 @@ class ClauseElement(Visitable):
 
     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
@@ -1342,7 +1342,7 @@ class ClauseElement(Visitable):
         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
@@ -1350,7 +1350,7 @@ class ClauseElement(Visitable):
         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.
         """
@@ -1365,7 +1365,7 @@ class ClauseElement(Visitable):
     def bind(self):
         """Returns the Engine or Connection to which this ClauseElement is
         bound, or None if none found.
-        
+
         """
         if self._bind is not None:
             return self._bind
@@ -1378,14 +1378,14 @@ class ClauseElement(Visitable):
                 return engine
         else:
             return None
-    
+
     @util.pending_deprecation('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:
@@ -1405,7 +1405,7 @@ class ClauseElement(Visitable):
     def scalar(self, *multiparams, **params):
         """Compile and execute this :class:`ClauseElement`, returning
         the result's scalar representation.
-        
+
         """
         return self.execute(*multiparams, **params).scalar()
 
@@ -1442,7 +1442,7 @@ class ClauseElement(Visitable):
             associated with a primary key `Column`.
 
         """
-        
+
         if not dialect:
             if bind:
                 dialect = bind.dialect
@@ -1454,13 +1454,13 @@ class ClauseElement(Visitable):
         c= self._compiler(dialect, bind=bind, **kw)
         #c.string = c.process(c.statement)
         return c
-        
+
     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())
@@ -1544,7 +1544,7 @@ class ColumnOperators(Operators):
         return self.operate(operators.le, other)
 
     __hash__ = Operators.__hash__
-    
+
     def __eq__(self, other):
         return self.operate(operators.eq, other)
 
@@ -1673,12 +1673,12 @@ class _CompareMixin(ColumnOperators):
 
     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)
@@ -1689,7 +1689,7 @@ class _CompareMixin(ColumnOperators):
             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
@@ -1722,12 +1722,12 @@ class _CompareMixin(ColumnOperators):
 
     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)
@@ -1743,8 +1743,8 @@ class _CompareMixin(ColumnOperators):
         elif isinstance(seq_or_selectable, (Selectable, _TextClause)):
             return self.__compare(op, seq_or_selectable,
                                   negate=negate_op)
-        
-            
+
+
         # Handle non selectable arguments as sequences
 
         args = []
@@ -1778,7 +1778,7 @@ class _CompareMixin(ColumnOperators):
 
     def __neg__(self):
         return _UnaryExpression(self, operator=operators.neg)
-        
+
     def startswith(self, other, escape=None):
         """Produce the clause ``LIKE '<other>%'``"""
 
@@ -1821,7 +1821,7 @@ class _CompareMixin(ColumnOperators):
 
     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.
@@ -1894,7 +1894,7 @@ class _CompareMixin(ColumnOperators):
           somecolumn.op('&')(0xff)
 
         is a bitwise AND of the value in somecolumn.
-          
+
         """
         return lambda other: self.__operate(operator, other)
 
@@ -1948,7 +1948,7 @@ class ColumnElement(ClauseElement, _CompareMixin):
     foreign_keys = []
     quote = None
     _label = None
-    
+
     @property
     def _select_iterable(self):
         return (self, )
@@ -1986,7 +1986,7 @@ class ColumnElement(ClauseElement, _CompareMixin):
             key = str(self)
         else:
             key = name
-            
+
         co = ColumnClause(name, selectable, type_=getattr(self,
                           'type', None))
         co.proxies = [self]
@@ -1995,12 +1995,12 @@ class ColumnElement(ClauseElement, _CompareMixin):
 
     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
@@ -2051,10 +2051,10 @@ class ColumnCollection(util.OrderedProperties):
         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
@@ -2089,13 +2089,13 @@ class ColumnCollection(util.OrderedProperties):
 
         """
         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:
 
@@ -2116,7 +2116,7 @@ class ColumnCollection(util.OrderedProperties):
     def clear(self):
         self._data.clear()
         self._all_cols.clear()
-        
+
     def remove(self, column):
         del self._data[column.key]
         self._all_cols.remove(column)
@@ -2125,12 +2125,12 @@ class ColumnCollection(util.OrderedProperties):
         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:
@@ -2151,15 +2151,15 @@ class ColumnCollection(util.OrderedProperties):
     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
 
 
@@ -2192,7 +2192,7 @@ class Selectable(ClauseElement):
 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
@@ -2233,19 +2233,19 @@ class FromClause(Selectable):
 
     def alias(self, name=None):
         """return an alias of this :class:`FromClause`.
-        
+
         For table objects, this has the effect of the table being rendered
-        as ``tablename AS aliasname`` in a SELECT statement.  
+        as ``tablename AS aliasname`` in a SELECT statement.
         For select objects, the effect is that of creating a named
         subquery, i.e. ``(select ...) AS aliasname``.
         The :func:`alias()` method is the general way to create
         a "subquery" out of an existing SELECT.
-        
+
         The ``name`` parameter is optional, and if left blank an 
         "anonymous" name will be generated at compile time, guaranteed
         to be unique against other anonymous constructs used in the
         same statement.
-        
+
         """
 
         return Alias(self, name)
@@ -2262,7 +2262,7 @@ class FromClause(Selectable):
     def replace_selectable(self, old, alias):
         """replace all occurences of FromClause 'old' with the given Alias 
         object, returning a copy of this :class:`FromClause`.
-        
+
         """
 
         return sqlutil.ClauseAdapter(alias).traverse(self)
@@ -2270,7 +2270,7 @@ class FromClause(Selectable):
     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:
@@ -2286,16 +2286,16 @@ class FromClause(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
@@ -2365,42 +2365,42 @@ class FromClause(Selectable):
     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
 
@@ -2433,14 +2433,14 @@ class _BindParamClause(ColumnElement):
           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
@@ -2451,10 +2451,10 @@ class _BindParamClause(ColumnElement):
           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.
@@ -2484,7 +2484,7 @@ class _BindParamClause(ColumnElement):
             self.type = type_()
         else:
             self.type = type_
-            
+
     def _clone(self):
         c = ClauseElement._clone(self)
         if self.unique:
@@ -2537,9 +2537,9 @@ class _TypeClause(ClauseElement):
 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()
@@ -2548,11 +2548,11 @@ class _Generative(object):
 
 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
@@ -2562,9 +2562,9 @@ class Executable(_Generative):
     def execution_options(self, **kw):
         """ Set non-SQL options for the statement which take effect during
         execution.
-        
+
         Current options include:
-        
+
         * autocommit - 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
@@ -2576,7 +2576,7 @@ class Executable(_Generative):
           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).
-          
+
         * stream_results - 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
@@ -2592,19 +2592,19 @@ class Executable(_Generative):
           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.
-          
+
           This option is usually more appropriate
           to use via the 
           :meth:`sqlalchemy.engine.base.Connection.execution_options()`
           method of :class:`Connection`, rather than upon individual 
           statement objects, though the effect is the same.
-          
+
         See also:
-        
+
             :meth:`sqlalchemy.engine.base.Connection.execution_options()`
 
             :meth:`sqlalchemy.orm.query.Query.execution_options()`
-            
+
         """
         self._execution_options = self._execution_options.union(kw)
 
@@ -2625,13 +2625,13 @@ class Executable(_Generative):
     def scalar(self, *multiparams, **params):
         """Compile and execute this :class:`.Executable`, returning the
         result's scalar representation.
-        
+
         """
         return self.execute(*multiparams, **params).scalar()
 
 # legacy, some outside users may be calling this
 _Executable = Executable
-    
+
 class _TextClause(Executable, ClauseElement):
     """Represent a literal SQL text fragment.
 
@@ -2645,7 +2645,7 @@ class _TextClause(Executable, ClauseElement):
     _execution_options = \
         Executable._execution_options.union({'autocommit'
             : PARSE_AUTOCOMMIT})
-    
+
     @property
     def _select_iterable(self):
         return (self,)
@@ -2685,7 +2685,7 @@ class _TextClause(Executable, ClauseElement):
         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:
@@ -2740,14 +2740,14 @@ class ClauseList(ClauseElement):
             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)
 
@@ -2815,7 +2815,7 @@ class BooleanClauseList(ClauseList, ColumnElement):
         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)
@@ -2831,7 +2831,7 @@ class _Tuple(ClauseList, ColumnElement):
                              _compared_to_type=self.type, unique=True)
             for o in obj
         ]).self_group()
-    
+
 
 class _Case(ColumnElement):
     __visit_name__ = 'case'
@@ -2893,7 +2893,7 @@ class _Case(ColumnElement):
 
 class FunctionElement(Executable, ColumnElement, FromClause):
     """Base for SQL function-oriented constructs."""
-    
+
     def __init__(self, *clauses, **kwargs):
         args = [_literal_as_binds(c, self.name) for c in clauses]
         self.clause_expr = ClauseList(
@@ -2937,7 +2937,7 @@ class FunctionElement(Executable, ColumnElement, FromClause):
         return _BindParamClause(None, obj, _compared_to_operator=operator, 
                                 _compared_to_type=self.type, unique=True)
 
-    
+
 class Function(FunctionElement):
     """Describe a named SQL function."""
 
@@ -2948,7 +2948,7 @@ class Function(FunctionElement):
         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):
@@ -3069,13 +3069,13 @@ class _BinaryExpression(ColumnElement):
             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
@@ -3149,7 +3149,7 @@ class _Exists(_UnaryExpression):
     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()
@@ -3158,7 +3158,7 @@ class _Exists(_UnaryExpression):
     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()
@@ -3326,7 +3326,7 @@ class Alias(FromClause):
         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
@@ -3400,10 +3400,10 @@ class _FromGrouping(FromClause):
 
     def __init__(self, element):
         self.element = element
-    
+
     def _init_collections(self):
         pass
-        
+
     @property
     def columns(self):
         return self.element.columns
@@ -3466,7 +3466,7 @@ class _Label(ColumnElement):
         self._type = type_
         self.quote = element.quote
         self.proxies = [element]
-        
+
     @util.memoized_property
     def type(self):
         return sqltypes.to_instance(
@@ -3476,7 +3476,7 @@ class _Label(ColumnElement):
     @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:
@@ -3485,7 +3485,7 @@ class _Label(ColumnElement):
                         type_=self._type)
         else:
             return self._element
-        
+
     @property
     def primary_key(self):
         return self.element.primary_key
@@ -3509,7 +3509,7 @@ class _Label(ColumnElement):
             e = self.element._make_proxy(selectable, name=self.name)
         else:
             e = column(self.name)._make_proxy(selectable=selectable)
-            
+
         e.proxies.append(self)
         return e
 
@@ -3549,14 +3549,14 @@ class ColumnClause(_Immutable, ColumnElement):
         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
@@ -3634,7 +3634,7 @@ class TableClause(_Immutable, FromClause):
     __visit_name__ = 'table'
 
     named_with_column = True
-    
+
     def __init__(self, name, *columns):
         super(TableClause, self).__init__()
         self.name = self.fullname = name
@@ -3643,10 +3643,10 @@ class TableClause(_Immutable, FromClause):
         self.foreign_keys = set()
         for c in columns:
             self.append_column(c)
-    
+
     def _init_collections(self):
         pass
-        
+
     @util.memoized_property
     def description(self):
         # Py3K
@@ -3668,7 +3668,7 @@ class TableClause(_Immutable, FromClause):
     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:
@@ -3704,7 +3704,7 @@ class _SelectBase(Executable, FromClause):
 
     _order_by_clause = ClauseList()
     _group_by_clause = ClauseList()
-    
+
     def __init__(self,
             use_labels=False,
             for_update=False,
@@ -3726,12 +3726,12 @@ class _SelectBase(Executable, FromClause):
         self._limit = limit
         self._offset = 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.
@@ -3806,10 +3806,10 @@ class _SelectBase(Executable, FromClause):
     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)
@@ -3818,10 +3818,10 @@ class _SelectBase(Executable, FromClause):
     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)
@@ -3889,7 +3889,7 @@ class CompoundSelect(_SelectBase):
     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
@@ -3900,7 +3900,7 @@ class CompoundSelect(_SelectBase):
         # 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:
@@ -3913,10 +3913,10 @@ class CompoundSelect(_SelectBase):
             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)
 
@@ -3950,7 +3950,7 @@ class CompoundSelect(_SelectBase):
 
             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]
@@ -3987,10 +3987,10 @@ class Select(_SelectBase):
     """
 
     __visit_name__ = 'select'
-    
+
     _prefixes = ()
     _hints = util.frozendict()
-    
+
     def __init__(self, 
                 columns, 
                 whereclause=None, 
@@ -4015,13 +4015,13 @@ class Select(_SelectBase):
 
         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:
@@ -4099,12 +4099,12 @@ class Select(_SelectBase):
         """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
@@ -4113,25 +4113,25 @@ class Select(_SelectBase):
         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.  "
@@ -4141,7 +4141,7 @@ class Select(_SelectBase):
     @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.
@@ -4192,7 +4192,7 @@ class Select(_SelectBase):
     def column(self, column):
         """return a new select() construct with the given column expression 
             added to its columns clause.
-            
+
         """
 
         column = _literal_as_column(column)
@@ -4207,7 +4207,7 @@ class Select(_SelectBase):
     def with_only_columns(self, columns):
         """return a new select() construct with its columns clause replaced 
             with the given columns.
-            
+
         """
 
         self._raw_columns = [
@@ -4220,7 +4220,7 @@ class Select(_SelectBase):
     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)
@@ -4229,7 +4229,7 @@ class Select(_SelectBase):
     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)
 
@@ -4237,7 +4237,7 @@ class Select(_SelectBase):
     def distinct(self):
         """return a new select() construct which will apply DISTINCT to its
         columns clause.
-         
+
          """
         self._distinct = True
 
@@ -4263,15 +4263,15 @@ class Select(_SelectBase):
     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().
 
@@ -4292,7 +4292,7 @@ class Select(_SelectBase):
     def append_column(self, column):
         """append the given column expression to the columns clause of this
         select() construct.
-        
+
         """
         column = _literal_as_column(column)
 
@@ -4306,7 +4306,7 @@ class Select(_SelectBase):
     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,)
@@ -4365,7 +4365,7 @@ class Select(_SelectBase):
     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.
@@ -4384,7 +4384,7 @@ class Select(_SelectBase):
     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)
 
@@ -4397,21 +4397,21 @@ class Select(_SelectBase):
     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)
 
@@ -4444,7 +4444,7 @@ class _UpdateBase(Executable, ClauseElement):
     _execution_options = \
         Executable._execution_options.union({'autocommit': True})
     kwargs = util.frozendict()
-    
+
     def _process_colparams(self, parameters):
         if isinstance(parameters, (list, tuple)):
             pp = {}
@@ -4478,21 +4478,21 @@ class _UpdateBase(Executable, ClauseElement):
                     "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
@@ -4500,7 +4500,7 @@ class _UpdateBase(Executable, ClauseElement):
         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.
@@ -4509,10 +4509,10 @@ class _UpdateBase(Executable, ClauseElement):
         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):
 
     __visit_name__ = 'values_base'
@@ -4555,9 +4555,9 @@ class Insert(_ValuesBase):
 
     """
     __visit_name__ = 'insert'
-    
+
     _prefixes = ()
-    
+
     def __init__(self, 
                 table, 
                 values=None, 
@@ -4573,7 +4573,7 @@ class Insert(_ValuesBase):
         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)
 
@@ -4641,7 +4641,7 @@ class Update(_ValuesBase):
     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,
@@ -4668,7 +4668,7 @@ class Delete(_UpdateBase):
         self._bind = bind
         self.table = table
         self._returning = returning
-        
+
         if whereclause is not None:
             self._whereclause = _literal_as_text(whereclause)
         else:
index a85d49a0a7c29f47846673d6cfccdd4511c8131a..10eaa577bca039f3d9b1e423e90e3b90eb0e67bb 100644 (file)
@@ -35,7 +35,7 @@ class AnsiFunction(GenericFunction):
 
 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)
index 3f96d5402708b109d64aac9f455af3807f0e8759..494f76f140c17de0b23616dd13fcf45230dda98e 100644 (file)
@@ -12,7 +12,7 @@
 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
@@ -101,7 +101,7 @@ def is_commutative(op):
     return op in _commutative
 
 _associative = _commutative.union([concat_op, and_, or_])
-    
+
 
 _smallest = symbol('_smallest')
 _largest = symbol('_largest')
index e4ad7c49833d5f382af3a32d2c80d330185f22f8..331f74b7cd401b75b216b64b771a0ddce27b1a2d 100644 (file)
@@ -13,7 +13,7 @@ from itertools import chain
 
 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):
@@ -33,7 +33,7 @@ def sort_tables(tables):
         tuples.extend(
             [parent, table] for parent in table._extra_dependencies
         )
-                            
+
     return list(topological.sort(tuples, tables))
 
 def find_join_source(clauses, join_to):
@@ -41,18 +41,18 @@ def find_join_source(clauses, join_to):
     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:
@@ -65,23 +65,23 @@ 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)
@@ -94,7 +94,7 @@ def find_tables(clause, check_columns=False,
 
 def find_columns(clause):
     """locate Column objects within the given expression."""
-    
+
     cols = util.column_set()
     visitors.traverse(clause, {}, {'column':cols.add})
     return cols
@@ -103,9 +103,9 @@ 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]
@@ -116,30 +116,30 @@ def clause_is_present(clause, search):
         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
 
@@ -149,15 +149,15 @@ def _quote_ddl_expr(element):
         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):
@@ -167,9 +167,9 @@ def expression_as_ddl(clause):
             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."""
 
@@ -186,23 +186,23 @@ def adapt_criterion_to_null(crit, nulls):
             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: This flag will cause the
     function to silently skip over foreign key resolution errors
     due to nonexistent tables - the assumption is that these
@@ -215,11 +215,11 @@ def join_condition(a, b, ignore_nonexistent_tables=False, a_subset=None):
     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
@@ -233,7 +233,7 @@ def join_condition(a, b, ignore_nonexistent_tables=False, a_subset=None):
                     continue
                 else:
                     raise
-                
+
             if col is not None:
                 crit.append(col == fk.parent)
                 constraints.add(fk.constraint)
@@ -254,7 +254,7 @@ def join_condition(a, b, ignore_nonexistent_tables=False, a_subset=None):
                     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 "\
@@ -279,17 +279,17 @@ def join_condition(a, b, ignore_nonexistent_tables=False, a_subset=None):
 
 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
@@ -311,11 +311,11 @@ class Annotated(object):
         # 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)
@@ -323,17 +323,17 @@ class Annotated(object):
         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:
@@ -344,7 +344,7 @@ class Annotated(object):
             # to this object's __dict__.
             clone.__dict__.update(self.__dict__)
             return Annotated(clone, self._annotations)
-    
+
     def __hash__(self):
         return hash(self.__element)
 
@@ -400,7 +400,7 @@ def _deep_deannotate(element):
 def splice_joins(left, right, stop_on=None):
     if left is None:
         return right
-        
+
     stack = [(right, None)]
 
     adapter = ClauseAdapter(left)
@@ -420,7 +420,7 @@ def splice_joins(left, right, stop_on=None):
             ret = right
 
     return ret
-    
+
 def reduce_columns(columns, *clauses, **kw):
     """given a list of columns, return a 'reduced' set based on natural equivalents.
 
@@ -433,14 +433,14 @@ def reduce_columns(columns, *clauses, **kw):
 
     \**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()
@@ -477,12 +477,12 @@ def reduce_columns(columns, *clauses, **kw):
 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
@@ -521,14 +521,14 @@ def criterion_as_pairs(expression, consider_as_foreign_keys=None,
 
 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"
@@ -564,10 +564,10 @@ def folded_equivalents(join, equivs=None):
 
 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
@@ -577,7 +577,7 @@ class AliasedRow(object):
         else:
             self.row = row
         self.map = map
-        
+
     def __contains__(self, key):
         return self.map[key] in self.row
 
@@ -593,7 +593,7 @@ class AliasedRow(object):
 
 class ClauseAdapter(visitors.ReplacingCloningVisitor):
     """Clones and modifies clauses based on column correspondence.
-    
+
     E.g.::
 
       table1 = Table('sometable', metadata,
@@ -623,7 +623,7 @@ class ClauseAdapter(visitors.ReplacingCloningVisitor):
         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)
 
@@ -646,17 +646,17 @@ class ClauseAdapter(visitors.ReplacingCloningVisitor):
             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, 
@@ -689,11 +689,11 @@ class ColumnAdapter(ClauseAdapter):
         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
@@ -702,17 +702,17 @@ class ColumnAdapter(ClauseAdapter):
         # the wrong column.
         if self.adapt_required and c is col:
             return None
-            
-        return c    
+
+        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)
index 91ded1130ab50678950f941443670d8248b87e99..8011aa109d960748a9a5f5c46361cb9f9ba61d65 100644 (file)
@@ -32,18 +32,18 @@ __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
-        
+
         # set up an optimized visit dispatch function
         # for use by the compiler
         if '__visit_name__' in cls.__dict__:
@@ -57,13 +57,13 @@ class VisitableType(type):
                     return getattr(visitor, 'visit_%s' % self.__visit_name__)(self, **kw)
 
             cls._compiler_dispatch = _compiler_dispatch
-        
+
         super(VisitableType, cls).__init__(clsname, bases, clsdict)
 
 class Visitable(object):
     """Base class for visitable objects, applies the
     ``VisitableType`` metaclass.
-    
+
     """
 
     __metaclass__ = VisitableType
@@ -71,27 +71,27 @@ class Visitable(object):
 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 = {}
@@ -100,11 +100,11 @@ class ClauseVisitor(object):
             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
@@ -112,9 +112,9 @@ class ClauseVisitor(object):
 
     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
@@ -123,7 +123,7 @@ class ClauseVisitor(object):
 class CloningVisitor(ClauseVisitor):
     """Base class for visitor objects which can traverse using 
     the cloned_traverse() function.
-    
+
     """
 
     def copy_and_process(self, list_):
@@ -139,12 +139,12 @@ class CloningVisitor(ClauseVisitor):
 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.
@@ -163,9 +163,9 @@ class ReplacingCloningVisitor(CloningVisitor):
 
 def iterate(obj, opts):
     """traverse the given expression structure, returning an iterator.
-    
+
     traversal is configured to be breadth-first.
-    
+
     """
     stack = deque([obj])
     while stack:
@@ -176,9 +176,9 @@ def iterate(obj, opts):
 
 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()
@@ -197,7 +197,7 @@ def traverse_using(iterator, obj, visitors):
         if meth:
             meth(target)
     return obj
-    
+
 def traverse(obj, opts, visitors):
     """traverse and visit the given expression structure using the default iterator."""
 
@@ -210,7 +210,7 @@ def traverse_depthfirst(obj, opts, visitors):
 
 def cloned_traverse(obj, opts, visitors):
     """clone the given expression structure, allowing modifications by visitors."""
-    
+
     cloned = util.column_dict()
 
     def clone(element):
@@ -237,7 +237,7 @@ def cloned_traverse(obj, opts, visitors):
 
 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', []))
 
index 5d3ec08fc13a1d4b76dc251c237bb52898b7f129..613dad82a6e7e4acf06c90f909f490ab29a06204 100644 (file)
@@ -46,7 +46,7 @@ class AbstractType(Visitable):
 
 class TypeEngine(AbstractType):
     """Base for built-in types."""
-    
+
     def copy_value(self, value):
         return value
 
@@ -93,22 +93,22 @@ class TypeEngine(AbstractType):
         objects alone.  Values such as dicts, lists which
         are serialized into strings are examples of "mutable" 
         column structures.
-        
+
         .. note:: This functionality is now superceded 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.
 
         """
@@ -117,10 +117,10 @@ class TypeEngine(AbstractType):
     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
@@ -137,12 +137,12 @@ class TypeEngine(AbstractType):
 
     def dialect_impl(self, dialect):
         """Return a dialect-specific implementation for this type."""
-        
+
         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."""
 
@@ -152,7 +152,7 @@ class TypeEngine(AbstractType):
             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."""
 
@@ -170,7 +170,7 @@ class TypeEngine(AbstractType):
         """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:
@@ -184,10 +184,10 @@ class TypeEngine(AbstractType):
 
     def _gen_dialect_impl(self, dialect):
         return dialect.type_descriptor(self)
-        
+
     def adapt(self, cls, **kw):
         return util.constructor_copy(self, cls, **kw)
-    
+
     def _coerce_compared_value(self, op, value):
         _coerced_type = _type_map.get(type(value), NULLTYPE)
         if _coerced_type is NULLTYPE or _coerced_type._type_affinity \
@@ -195,19 +195,19 @@ class TypeEngine(AbstractType):
             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):
         # 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"):
@@ -216,7 +216,7 @@ class TypeEngine(AbstractType):
             return getattr(__import__(mod).dialects, tokens[-1]).dialect()
         else:
             return default.DefaultDialect()
-        
+
     def __str__(self):
         # Py3K
         #return unicode(self.compile())
@@ -276,24 +276,24 @@ class UserDefinedType(TypeEngine):
     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.
@@ -308,7 +308,7 @@ class TypeDecorator(TypeEngine):
           '''
 
           impl = types.Unicode
-          
+
           def process_bind_param(self, value, dialect):
               return "PREFIX:" + value
 
@@ -329,40 +329,40 @@ class TypeDecorator(TypeEngine):
     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``.  
-    
+    "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()
@@ -380,8 +380,8 @@ class TypeDecorator(TypeEngine):
                                  "'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:
@@ -406,7 +406,7 @@ class TypeDecorator(TypeEngine):
 
     def type_engine(self, dialect):
         """Return a TypeEngine instance for this TypeDecorator.
-        
+
         """
         adapted = dialect.type_descriptor(self)
         if adapted is not self:
@@ -471,28 +471,28 @@ class TypeDecorator(TypeEngine):
             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):
         return self.coerce_compared_value(op, value)
-        
+
     def copy(self):
         instance = self.__class__.__new__(self.__class__)
         instance.__dict__.update(self.__dict__)
@@ -519,7 +519,7 @@ class TypeDecorator(TypeEngine):
         .. note:: This functionality is now superceded by the
           ``sqlalchemy.ext.mutable`` extension described in 
           :ref:`mutable_toplevel`.
-        
+
         """
         return self.impl.is_mutable()
 
@@ -534,14 +534,14 @@ 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 superceded 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
@@ -549,7 +549,7 @@ class MutableType(object):
     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 
@@ -557,12 +557,12 @@ class MutableType(object):
     :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
@@ -577,21 +577,21 @@ class MutableType(object):
         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
 
@@ -672,13 +672,13 @@ class Concatenable(object):
 
 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()
@@ -737,12 +737,12 @@ class String(Concatenable, TypeEngine):
           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
@@ -767,7 +767,7 @@ class String(Concatenable, TypeEngine):
         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 '
@@ -781,7 +781,7 @@ class String(Concatenable, TypeEngine):
         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 \
@@ -818,16 +818,16 @@ class String(Concatenable, TypeEngine):
         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).   
+                # in most cases, we check for it (decode will fail).
                 def process(value):
                     if isinstance(value, unicode):
                         return value
@@ -862,7 +862,7 @@ class Unicode(String):
     ``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 
@@ -870,7 +870,7 @@ class Unicode(String):
     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
@@ -890,7 +890,7 @@ class Unicode(String):
     """
 
     __visit_name__ = 'unicode'
-    
+
     def __init__(self, length=None, **kwargs):
         """
         Create a Unicode-converting String type.
@@ -901,10 +901,10 @@ class Unicode(String):
           *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)
@@ -947,7 +947,7 @@ class Integer(_DateAffinity, TypeEngine):
 
     def get_dbapi_type(self, dbapi):
         return dbapi.NUMBER
-    
+
     @util.memoized_property
     def _expression_adaptations(self):
         # TODO: need a dictionary object that will
@@ -1019,16 +1019,16 @@ class Numeric(_DateAffinity, TypeEngine):
        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")
@@ -1055,14 +1055,14 @@ class Numeric(_DateAffinity, TypeEngine):
           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.  
-          
+          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-
@@ -1072,7 +1072,7 @@ class Numeric(_DateAffinity, TypeEngine):
         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
@@ -1100,7 +1100,7 @@ class Numeric(_DateAffinity, TypeEngine):
                           '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(
@@ -1143,24 +1143,24 @@ class Numeric(_DateAffinity, TypeEngine):
         }
 
 class Float(Numeric):
-    """A type for ``float`` numbers.  
-    
+    """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.
@@ -1229,7 +1229,7 @@ class DateTime(_DateAffinity, TypeEngine):
                 DateTime:Interval,
             },
         }
-        
+
 
 class Date(_DateAffinity,TypeEngine):
     """A type for ``datetime.date()`` objects."""
@@ -1250,12 +1250,12 @@ class Date(_DateAffinity,TypeEngine):
             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
@@ -1330,10 +1330,10 @@ class _Binary(TypeEngine):
             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.
 
@@ -1363,7 +1363,7 @@ class LargeBinary(_Binary):
 
 class Binary(LargeBinary):
     """Deprecated.  Renamed to LargeBinary."""
-    
+
     def __init__(self, *arg, **kw):
         util.warn_deprecated('The Binary type has been renamed to '
                              'LargeBinary.')
@@ -1371,13 +1371,13 @@ class Binary(LargeBinary):
 
 class SchemaType(object):
     """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.
-    
+
     """
-    
+
     def __init__(self, **kw):
         self.name = kw.pop('name', None)
         self.quote = kw.pop('quote', None)
@@ -1388,10 +1388,10 @@ class SchemaType(object):
                     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, table, column):
         table.append_ddl_listener('before-create',
                                   util.portable_instancemethod(
@@ -1404,14 +1404,14 @@ class SchemaType(object):
                     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)
@@ -1426,7 +1426,7 @@ class SchemaType(object):
         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):
@@ -1446,22 +1446,22 @@ class SchemaType(object):
         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.
 
@@ -1513,7 +1513,7 @@ class Enum(String, SchemaType):
                     break
             else:
                 convert_unicode = False
-        
+
         if self.enums:
             length =max(len(x) for x in self.enums)
         else:
@@ -1527,11 +1527,11 @@ class Enum(String, SchemaType):
     def _should_create_constraint(self, compiler):
         return not self.native_enum or \
                     not compiler.dialect.supports_native_enum
-    
+
     def _set_table(self, table, column):
         if self.native_enum:
             SchemaType._set_table(self, table, column)
-            
+
 
         e = schema.CheckConstraint(
                         column.in_(self.enums),
@@ -1540,7 +1540,7 @@ class Enum(String, SchemaType):
                                         self._should_create_constraint)
                     )
         table.append_constraint(e)
-        
+
     def adapt(self, impltype, **kw):
         if issubclass(impltype, Enum):
             return impltype(name=self.name, 
@@ -1601,13 +1601,13 @@ class PickleType(MutableType, TypeDecorator):
         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
@@ -1655,11 +1655,11 @@ class PickleType(MutableType, TypeDecorator):
 
     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
 
@@ -1676,25 +1676,25 @@ class Boolean(TypeEngine, SchemaType):
 
     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, table, column):
         if not self.create_constraint:
             return
-            
+
         e = schema.CheckConstraint(
                         column.in_([0, 1]),
                         name=self.name,
@@ -1702,13 +1702,13 @@ class Boolean(TypeEngine, SchemaType):
                                     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
@@ -1729,7 +1729,7 @@ class Interval(_DateAffinity, TypeDecorator):
     (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
@@ -1739,20 +1739,20 @@ class Interval(_DateAffinity, TypeDecorator):
                         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).  
+          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
@@ -1764,7 +1764,7 @@ class Interval(_DateAffinity, TypeDecorator):
             return cls._adapt_from_generic_interval(self, **kw)
         else:
             return cls(**kw)
-    
+
     def bind_processor(self, dialect):
         impl_processor = self.impl.bind_processor(dialect)
         epoch = self.epoch
index 9ce223939ec967c0b64d77c648d7929fa2c4944e..6950aa8e6d2606111769888983936f2e3ccf224d 100644 (file)
@@ -15,7 +15,7 @@ from _collections import NamedTuple, ImmutableContainer, frozendict, \
     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, \
index 4f9c5dc8aa72f322803ec3d208e1dd0f2e3b8a7f..269a3d53901fb3c0eca4b5cd48a6ca603630266e 100644 (file)
@@ -18,9 +18,9 @@ EMPTY_SET = frozenset()
 
 class NamedTuple(tuple):
     """tuple() subclass that adds labeled names.
-    
+
     Is also pickleable.
-    
+
     """
 
     def __new__(cls, vals, labels=None):
@@ -40,7 +40,7 @@ class ImmutableContainer(object):
     __delitem__ = __setitem__ = __setattr__ = _immutable
 
 class frozendict(ImmutableContainer, dict):
-    
+
     clear = pop = popitem = setdefault = \
         update = ImmutableContainer._immutable
 
@@ -62,7 +62,7 @@ class frozendict(ImmutableContainer, dict):
             d2 = frozendict(self)
             dict.update(d2, d)
             return d2
-            
+
     def __repr__(self):
         return "frozendict(%s)" % dict.__repr__(self)
 
@@ -107,12 +107,12 @@ class Properties(object):
 
     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)
 
@@ -136,12 +136,12 @@ class OrderedProperties(Properties):
     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."""
 
@@ -266,10 +266,10 @@ class OrderedSet(set):
 
     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)
 
@@ -340,11 +340,11 @@ class IdentitySet(object):
 
     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:
@@ -501,10 +501,10 @@ class IdentitySet(object):
         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
@@ -544,7 +544,7 @@ class OrderedIdentitySet(IdentitySet):
         # 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()
@@ -564,7 +564,7 @@ if sys.version_info >= (2, 5):
 
         def __init__(self, creator):
             self.creator = creator
-            
+
         def __missing__(self, key):
             self[key] = val = self.creator(key)
             return val
@@ -574,7 +574,7 @@ else:
 
         def __init__(self, creator):
             self.creator = creator
-            
+
         def __getitem__(self, key):
             try:
                 return dict.__getitem__(self, key)
@@ -652,13 +652,13 @@ def to_column_set(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.
@@ -748,7 +748,7 @@ class WeakIdentityMapping(weakref.WeakKeyDictionary):
             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)
@@ -761,7 +761,7 @@ class WeakIdentityMapping(weakref.WeakKeyDictionary):
 class LRUCache(dict):
     """Dictionary with 'squishy' removal of least
     recently used items.
-    
+
     """
     def __init__(self, capacity=100, threshold=.5):
         self.capacity = capacity
@@ -809,7 +809,7 @@ class LRUCache(dict):
 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.
@@ -823,14 +823,14 @@ class ScopedRegistry(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
@@ -845,17 +845,17 @@ class ScopedRegistry(object):
 
     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:
@@ -864,7 +864,7 @@ class ScopedRegistry(object):
 class ThreadLocalRegistry(ScopedRegistry):
     """A :class:`.ScopedRegistry` that uses a ``threading.local()`` 
     variable for storage.
-    
+
     """
     def __init__(self, createfunc):
         self.createfunc = createfunc
index fb2a146331f666d0c9e41026f97b1d8081d8d1a3..6b6051973fe801b347220c49d65a7acfdce05a09 100644 (file)
@@ -52,7 +52,7 @@ else:
 # a controversial feature, required by MySQLdb currently
 def buffer(x):
     return x 
-    
+
 # Py2K
 buffer = getattr(__builtin__, 'buffer', buffer)
 # end Py2K
@@ -136,7 +136,7 @@ except ImportError:
 class _probe(dict):
     def __missing__(self, key):
         return 1
-        
+
 try:
     try:
         _probe()['missing']
index 532594b72dce5c585a3e323f6b5d50bf8d4cfdee..d9018a26d9a7cc740fa17ae5be8a78df53c7ce8c 100644 (file)
@@ -73,7 +73,7 @@ def pending_deprecation(version, message=None,
 
     if message is None:
         message = "Call to deprecated function %(func)s"
-    
+
     def decorate(fn):
         return _decorate_with_warning(
             fn, exc.SAPendingDeprecationWarning,
@@ -87,13 +87,13 @@ def _sanitize_restructured_text(text):
             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)
index 38260cd66a7fcda6664d17fa499d3d0a06de42bf..4ac78bd169582786d5d4c3da2b0d8f07dc23b939 100644 (file)
@@ -59,10 +59,10 @@ def get_cls_kwargs(cls):
     __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__:
@@ -79,10 +79,10 @@ def get_cls_kwargs(cls):
         if not ctr or not isinstance(ctr, types.FunctionType):
             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:
@@ -106,12 +106,12 @@ except ImportError:
 
 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):
@@ -203,7 +203,7 @@ def getargspec_init(method):
         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."""
 
@@ -215,7 +215,7 @@ def unbound_method_to_callable(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
@@ -223,7 +223,7 @@ class portable_instancemethod(object):
 
     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.
 
@@ -468,22 +468,22 @@ class group_expirable_memoized_property(object):
 
 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:
@@ -501,7 +501,7 @@ class importlater(object):
             for token in self._il_path.split(".")[1:]:
                 m = getattr(m, token)
             return m
-        
+
     def __getattr__(self, key):
         try:
             attr = getattr(self.module, key)
@@ -528,7 +528,7 @@ def asbool(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:
@@ -536,7 +536,7 @@ def bool_or_str(*text):
         else:
             return asbool(obj)
     return bool_or_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
@@ -552,11 +552,11 @@ def coerce_kw_type(kw, key, type_, flexi_bool=True):
 
 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)
@@ -645,13 +645,13 @@ class classproperty(property):
     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)
 
@@ -719,15 +719,15 @@ def warn_exception(func, *args, **kwargs):
 
 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)
index aeb212d4df973963459b83e931745af936621009..8f340647222e376347c76c7a99caadaed42a0f44 100644 (file)
@@ -17,7 +17,7 @@ def sort_as_subsets(tuples, allitems):
     edges = util.defaultdict(set)
     for parent, child in tuples:
         edges[child].add(parent)
-    
+
     todo = set(allitems)
 
     while todo:
@@ -55,7 +55,7 @@ def find_cycles(tuples, allitems):
         edges[parent].add(child)
 
     output = set()
-    
+
     while todo:
         node = todo.pop()
         stack = [node]
@@ -66,7 +66,7 @@ def find_cycles(tuples, allitems):
                     cyc = stack[stack.index(node):]
                     todo.difference_update(cyc)
                     output.update(cyc)
-                    
+
                 if node in todo:
                     stack.append(node)
                     todo.remove(node)
index f2c5d9801d3a8d2afd6f537e59c71aff9c47a6f5..8c09540a1ad643606c6b9cf844058a2cded31f48 100644 (file)
--- a/sa2to3.py
+++ b/sa2to3.py
@@ -29,7 +29,7 @@ def preprocess(data):
                     yield line
             else:
                 yield line
-    
+
     def consume_py3k():
         yield "# start Py3K"
         while lines:
@@ -42,7 +42,7 @@ def preprocess(data):
                 lines.insert(0, line)
                 break
         yield "# end Py3K"
-    
+
     def consume_py2k():
         yield "# start Py2K"
         while lines:
index e3bdfeff8ebe7abc06e9ac23c71b85704ee37788..cf379d89899a24cd52eaba1c4a38d9f022fbf29f 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -16,7 +16,7 @@ import re
 extra = {}
 if sys.version_info >= (3, 0):
     # monkeypatch our preprocessor
-    # onto the 2to3 tool.  
+    # onto the 2to3 tool.
     from sa2to3 import refactor_string
     from lib2to3.refactor import RefactoringTool
     RefactoringTool.refactor_string = refactor_string
@@ -84,7 +84,7 @@ setup(name = "SQLAlchemy",
 
       tests_require = ['nose >= 0.11'],
       test_suite = "sqla_nose",
-      
+
       long_description = """\
 SQLAlchemy is:
 
index a5d5d973b38ffe42ce7195fc902240774abdf11f..18d0118f142b80d2ceeca0161c292afe3eb5469a 100644 (file)
@@ -5,7 +5,7 @@ from sqlalchemy.engine import default
 class CompileTest(TestBase, AssertsExecutionResults):
     @classmethod
     def setup_class(cls):
-        
+
         global t1, t2, metadata
         metadata = MetaData()
         t1 = Table('t1', metadata,
@@ -29,9 +29,9 @@ class CompileTest(TestBase, AssertsExecutionResults):
         from sqlalchemy import types
         for t in types._type_map.values():
             t._type_affinity
-        
+
         cls.dialect = default.DefaultDialect()
-        
+
     @profiling.function_call_count(versions={'2.7':58, '2.6':58,
                                             '3':64})
     def test_insert(self):
index 7f7cbcfb19966cfeecbf32d191a4837c17a6e773..3e225ad0889464507448c25859b153eb8010ca43 100644 (file)
@@ -32,7 +32,7 @@ class B(_base.ComparableEntity):
 def profile_memory(func):
     # run the test 50 times.  if length of gc.get_objects()
     # keeps growing, assert false
-    
+
     def profile(*args):
         gc_collect()
         samples = [0 for x in range(0, 50)]
@@ -40,11 +40,11 @@ def profile_memory(func):
             func(*args)
             gc_collect()
             samples[x] = len(gc.get_objects())
-                
+
         print "sample gc sizes:", samples
 
         assert len(_sessions) == 0
-        
+
         for x in samples[-4:]:
             if x != samples[-5]:
                 flatline = False
@@ -53,7 +53,7 @@ def profile_memory(func):
             flatline = True
 
         # object count is bigger than when it started
-        if not flatline and samples[-1] > samples[0]:  
+        if not flatline and samples[-1] > samples[0]:
             for x in samples[1:-2]:
                 # see if a spike bigger than the endpoint exists
                 if x > samples[-1]:
@@ -74,19 +74,19 @@ class EnsureZeroed(_base.ORMTest):
         _mapper_registry.clear()
 
 class MemUsageTest(EnsureZeroed):
-    
+
     # ensure a pure growing test trips the assertion
     @testing.fails_if(lambda: True)
     def test_fixture(self):
         class Foo(object):
             pass
-            
+
         x = []
         @profile_memory
         def go():
             x[-1:] = [Foo(), Foo(), Foo(), Foo(), Foo(), Foo()]
         go()
-            
+
     def test_session(self):
         metadata = MetaData(testing.db)
 
@@ -179,7 +179,7 @@ class MemUsageTest(EnsureZeroed):
                                         'pool_logging_name':'BAR'}
                                     )
             sess = create_session(bind=engine)
-            
+
             a1 = A(col2="a1")
             a2 = A(col2="a2")
             a3 = A(col2="a3")
@@ -210,14 +210,14 @@ class MemUsageTest(EnsureZeroed):
         metadata.drop_all()
         del m1, m2, m3
         assert_no_mappers()
-    
+
     def test_ad_hoc_types(self):
         """test storage of bind processors, result processors
         in dialect-wide registry."""
-        
+
         from sqlalchemy.dialects import mysql, postgresql, sqlite
         from sqlalchemy import types
-        
+
         eng = engines.testing_engine()
         for args in (
             (types.Integer, ),
@@ -236,24 +236,24 @@ class MemUsageTest(EnsureZeroed):
                 bp = type_._cached_bind_processor(eng.dialect)
                 rp = type_._cached_result_processor(eng.dialect, 0)
             go()
-        
+
         assert not eng.dialect._type_memos
-            
-            
+
+
     def test_many_updates(self):
         metadata = MetaData(testing.db)
-        
+
         wide_table = Table('t', metadata,
             Column('id', Integer, primary_key=True,
                                 test_needs_autoincrement=True),
             *[Column('col%d' % i, Integer) for i in range(10)]
         )
-        
+
         class Wide(object):
             pass
-        
+
         mapper(Wide, wide_table, _compiled_cache_size=10)
-        
+
         metadata.create_all()
         session = create_session()
         w1 = Wide()
@@ -262,7 +262,7 @@ class MemUsageTest(EnsureZeroed):
         session.close()
         del session
         counter = [1]
-        
+
         @profile_memory
         def go():
             session = create_session()
@@ -279,12 +279,12 @@ class MemUsageTest(EnsureZeroed):
             session.flush()
             session.close()
             counter[0] += 1
-            
+
         try:
             go()
         finally:
             metadata.drop_all()
-    
+
     @testing.fails_if(lambda : testing.db.dialect.name == 'sqlite' \
                       and testing.db.dialect.dbapi.version_info >= (2,
                       5),
@@ -313,7 +313,7 @@ class MemUsageTest(EnsureZeroed):
             go()
         finally:
             metadata.drop_all()
-        
+
     def test_mapper_reset(self):
         metadata = MetaData(testing.db)
 
@@ -491,7 +491,7 @@ class MemUsageTest(EnsureZeroed):
             # dont need to clear_mappers()
             del B
             del A
-            
+
         metadata.create_all()
         try:
             go()
@@ -538,8 +538,8 @@ class MemUsageTest(EnsureZeroed):
             go()
         finally:
             metadata.drop_all()
-            
-            
+
+
     def test_mutable_identity(self):
         metadata = MetaData(testing.db)
 
@@ -548,16 +548,16 @@ class MemUsageTest(EnsureZeroed):
                                 test_needs_autoincrement=True),
             Column('col2', PickleType(comparator=operator.eq, mutable=True))
             )
-        
+
         class Foo(object):
             def __init__(self, col2):
                 self.col2 = col2
-        
+
         mapper(Foo, table1)
         metadata.create_all()
-        
+
         session = sessionmaker()()
-        
+
         def go():
             obj = [
                 Foo({'a':1}),
@@ -573,17 +573,17 @@ class MemUsageTest(EnsureZeroed):
                 Foo({'k':1}),
                 Foo({'l':1}),
             ]
-            
+
             session.add_all(obj)
             session.commit()
-            
+
             testing.eq_(len(session.identity_map._mutable_attrs), 12)
             testing.eq_(len(session.identity_map), 12)
             obj = None
             gc_collect()
             testing.eq_(len(session.identity_map._mutable_attrs), 0)
             testing.eq_(len(session.identity_map), 0)
-            
+
         try:
             go()
         finally:
index 84a9fd0259a0a98d590f43a67432e1af6bc0a9c5..7c89d22fd4d7647a78ee025c2c7cb07560485483 100644 (file)
@@ -96,21 +96,21 @@ class MergeTest(_base.MappedTest):
 
 class LoadManyToOneFromIdentityTest(_base.MappedTest):
     """test overhead associated with many-to-one fetches.
-    
+
     Prior to the refactor of LoadLazyAttribute and 
     query._get(), the load from identity map took 2x
     as many calls (65K calls here instead of around 33K)
     to load 1000 related objects from the identity map.
-    
+
     """
-    
+
     # only need to test for unexpected variance in a large call 
     # count here,
     # so remove some platforms that have wildly divergent
     # callcounts.
     __requires__ = 'python25',
     __unsupported_on__ = 'postgresql+pg8000',
-    
+
     @classmethod
     def define_tables(cls, metadata):
         parent = Table('parent', metadata, 
@@ -118,7 +118,7 @@ class LoadManyToOneFromIdentityTest(_base.MappedTest):
                        Column('data', String(20)),
                        Column('child_id', Integer, ForeignKey('child.id'))
                        )
-                       
+
         child = Table('child', metadata, 
                     Column('id', Integer,primary_key=True),
                   Column('data', String(20))
@@ -154,13 +154,13 @@ class LoadManyToOneFromIdentityTest(_base.MappedTest):
             } 
             for i in xrange(1, 1000)
         ])
-    
+
     @testing.resolve_artifact_names
     def test_many_to_one_load_no_identity(self):
         sess = Session()
         parents = sess.query(Parent).all()
-        
-        
+
+
         @profiling.function_call_count(108019, variance=.2)
         def go():
             for p in parents:
@@ -172,11 +172,11 @@ class LoadManyToOneFromIdentityTest(_base.MappedTest):
         sess = Session()
         parents = sess.query(Parent).all()
         children = sess.query(Child).all()
-        
+
         @profiling.function_call_count(17987, {'3':18987})
         def go():
             for p in parents:
                 p.child
         go()
-        
-        
+
+
index a3c0f725e89b80fb4d058edeb507e4b7f3b5fb4a..d0486fa0bdf56e8a4dabf62b464e8723c35f0d04 100644 (file)
@@ -7,7 +7,7 @@ class QueuePoolTest(TestBase, AssertsExecutionResults):
     class Connection(object):
         def rollback(self):
             pass
-            
+
         def close(self):
             pass
 
index 51199eb3adfce29a6e585622bd7185fb99978129..a0b16cb52b8fe8805b3a5c2a179315788591c903 100644 (file)
@@ -25,11 +25,11 @@ class ResultSetTest(TestBase, AssertsExecutionResults):
         t2.insert().execute([dict(('field%d' % fnum, u'value%d' % fnum)
                             for fnum in range(NUM_FIELDS)) for r_num in
                             range(NUM_RECORDS)])
-        
+
         # warm up type caches
         t.select().execute().fetchall()
         t2.select().execute().fetchall()
-        
+
     def teardown(self):
         metadata.drop_all()
 
@@ -54,14 +54,14 @@ class ResultSetTest(TestBase, AssertsExecutionResults):
 
 class ExecutionTest(TestBase):
     __only_on__ = 'sqlite'
-    
+
     def test_minimal_connection_execute(self):
         # create an engine without any instrumentation.
         e = create_engine('sqlite://')
         c = e.connect()
         # ensure initial connect activities complete
         c.execute("select 1")
-        
+
         @profiling.function_call_count(versions={'2.7':36, '2.6':35, '2.5':35, 
                                                     '2.4':21, '3':34}, 
                                             variance=.10)
index 8c1cb1c600ff7b26b430e466f42262266f47d79e..648efed438e5eb4fe4b1882c75324aedfb0ccc6a 100644 (file)
@@ -16,14 +16,14 @@ metadata = None
 class ZooMarkTest(TestBase):
 
     """Runs the ZooMark and squawks if method counts vary from the norm.
-    
+
     Each test has an associated `call_range`, the total number of
     accepted function calls made during the test.  The count can vary
     between Python 2.4 and 2.5.
-    
+
     Unlike a unit test, this is a ordered collection of steps.  Running
     components individually will fail.
-    
+
     """
 
     __only_on__ = 'postgresql+psycopg2'
index 0ea1bbd25b4ebf4a991b8c10a78c244e207c9681..ce2cfdc8e3726412687b3068737c9a10a59240b6 100644 (file)
@@ -17,14 +17,14 @@ metadata = None
 class ZooMarkTest(TestBase):
 
     """Runs the ZooMark and squawks if method counts vary from the norm.
-    
+
     Each test has an associated `call_range`, the total number of
     accepted function calls made during the test.  The count can vary
     between Python 2.4 and 2.5.
-    
+
     Unlike a unit test, this is a ordered collection of steps.  Running
     components individually will fail.
-    
+
     """
 
     __only_on__ = 'postgresql+psycopg2'
@@ -94,7 +94,7 @@ class ZooMarkTest(TestBase):
                   Admission=4.95)
         session.add(wap)
         sdz = Zoo(Name=u'San Diego Zoo', Founded=datetime.date(1835, 9,
-                  13), Opens=datetime.time(9, 0, 0), Admission=0)  
+                  13), Opens=datetime.time(9, 0, 0), Admission=0)
         session.add(sdz)
         bio = Zoo(Name=u'Montr\xe9al Biod\xf4me',
                   Founded=datetime.date(1992, 6, 19),
index e64ec3b81bc0c476d59e8e252087bda3de9fb6d9..e894a1f74fcbb7e6ad1ac5c9c1d4f46bdcb6299d 100644 (file)
@@ -5,39 +5,39 @@ from sqlalchemy import event, exc, util
 
 class TestEvents(TestBase):
     """Test class- and instance-level event registration."""
-    
+
     def setUp(self):
         global Target
-        
+
         assert 'event_one' not in event._registrars
         assert 'event_two' not in event._registrars
-        
+
         class TargetEvents(event.Events):
             def event_one(self, x, y):
                 pass
-            
+
             def event_two(self, x):
                 pass
-                
+
         class Target(object):
             dispatch = event.dispatcher(TargetEvents)
-    
+
     def tearDown(self):
         event._remove_dispatcher(Target.__dict__['dispatch'].events)
-    
+
     def test_register_class(self):
         def listen(x, y):
             pass
-        
+
         event.listen(Target, "event_one", listen)
-        
+
         eq_(len(Target().dispatch.event_one), 1)
         eq_(len(Target().dispatch.event_two), 0)
 
     def test_register_instance(self):
         def listen(x, y):
             pass
-        
+
         t1 = Target()
         event.listen(t1, "event_one", listen)
 
@@ -45,7 +45,7 @@ class TestEvents(TestBase):
         eq_(len(t1.dispatch.event_one), 1)
         eq_(len(Target().dispatch.event_two), 0)
         eq_(len(t1.dispatch.event_two), 0)
-    
+
     def test_register_class_instance(self):
         def listen_one(x, y):
             pass
@@ -54,7 +54,7 @@ class TestEvents(TestBase):
             pass
 
         event.listen(Target, "event_one", listen_one)
-        
+
         t1 = Target()
         event.listen(t1, "event_one", listen_two)
 
@@ -62,20 +62,20 @@ class TestEvents(TestBase):
         eq_(len(t1.dispatch.event_one), 2)
         eq_(len(Target().dispatch.event_two), 0)
         eq_(len(t1.dispatch.event_two), 0)
-        
+
         def listen_three(x, y):
             pass
-        
+
         event.listen(Target, "event_one", listen_three)
         eq_(len(Target().dispatch.event_one), 2)
         eq_(len(t1.dispatch.event_one), 3)
-        
+
 class TestAcceptTargets(TestBase):
     """Test default target acceptance."""
-    
+
     def setUp(self):
         global TargetOne, TargetTwo
-        
+
         class TargetEventsOne(event.Events):
             def event_one(self, x, y):
                 pass
@@ -83,37 +83,37 @@ class TestAcceptTargets(TestBase):
         class TargetEventsTwo(event.Events):
             def event_one(self, x, y):
                 pass
-                
+
         class TargetOne(object):
             dispatch = event.dispatcher(TargetEventsOne)
 
         class TargetTwo(object):
             dispatch = event.dispatcher(TargetEventsTwo)
-    
+
     def tearDown(self):
         event._remove_dispatcher(TargetOne.__dict__['dispatch'].events)
         event._remove_dispatcher(TargetTwo.__dict__['dispatch'].events)
-        
+
     def test_target_accept(self):
         """Test that events of the same name are routed to the correct
         collection based on the type of target given.
-        
+
         """
         def listen_one(x, y):
             pass
 
         def listen_two(x, y):
             pass
-        
+
         def listen_three(x, y):
             pass
 
         def listen_four(x, y):
             pass
-            
+
         event.listen(TargetOne, "event_one", listen_one)
         event.listen(TargetTwo, "event_one", listen_two)
-        
+
         eq_(
             list(TargetOne().dispatch.event_one),
             [listen_one]
@@ -129,7 +129,7 @@ class TestAcceptTargets(TestBase):
 
         event.listen(t1, "event_one", listen_three)
         event.listen(t2, "event_one", listen_four)
-        
+
         eq_(
             list(t1.dispatch.event_one),
             [listen_one, listen_three]
@@ -139,13 +139,13 @@ class TestAcceptTargets(TestBase):
             list(t2.dispatch.event_one),
             [listen_two, listen_four]
         )
-        
+
 class TestCustomTargets(TestBase):
     """Test custom target acceptance."""
 
     def setUp(self):
         global Target
-        
+
         class TargetEvents(event.Events):
             @classmethod
             def _accept_with(cls, target):
@@ -153,7 +153,7 @@ class TestCustomTargets(TestBase):
                     return Target
                 else:
                     return None
-                    
+
             def event_one(self, x, y):
                 pass
 
@@ -162,30 +162,30 @@ class TestCustomTargets(TestBase):
 
     def tearDown(self):
         event._remove_dispatcher(Target.__dict__['dispatch'].events)
-    
+
     def test_indirect(self):
         def listen(x, y):
             pass
-        
+
         event.listen("one", "event_one", listen)
 
         eq_(
             list(Target().dispatch.event_one),
             [listen]
         )
-        
+
         assert_raises(
             exc.InvalidRequestError, 
             event.listen,
             listen, "event_one", Target
         )
-        
+
 class TestListenOverride(TestBase):
     """Test custom listen functions which change the listener function signature."""
-    
+
     def setUp(self):
         global Target
-        
+
         class TargetEvents(event.Events):
             @classmethod
             def _listen(cls, target, identifier, fn, add=False):
@@ -194,9 +194,9 @@ class TestListenOverride(TestBase):
                         fn(x + y)
                 else:
                     adapt = fn
-                    
+
                 event.Events._listen(target, identifier, adapt)
-                    
+
             def event_one(self, x, y):
                 pass
 
@@ -205,43 +205,43 @@ class TestListenOverride(TestBase):
 
     def tearDown(self):
         event._remove_dispatcher(Target.__dict__['dispatch'].events)
-    
+
     def test_listen_override(self):
         result = []
         def listen_one(x):
             result.append(x)
-            
+
         def listen_two(x, y):
             result.append((x, y))
-        
+
         event.listen(Target, "event_one", listen_one, add=True)
         event.listen(Target, "event_one", listen_two)
 
         t1 = Target()
         t1.dispatch.event_one(5, 7)
         t1.dispatch.event_one(10, 5)
-        
+
         eq_(result,
             [
                 12, (5, 7), 15, (10, 5)
             ]
         )
-        
+
 class TestPropagate(TestBase):
     def setUp(self):
         global Target
-        
+
         class TargetEvents(event.Events):
             def event_one(self, arg):
                 pass
-            
+
             def event_two(self, arg):
                 pass
-                
+
         class Target(object):
             dispatch = event.dispatcher(TargetEvents)
-            
-    
+
+
     def test_propagate(self):
         result = []
         def listen_one(target, arg):
@@ -249,16 +249,16 @@ class TestPropagate(TestBase):
 
         def listen_two(target, arg):
             result.append((target, arg))
-        
+
         t1 = Target()
-        
+
         event.listen(t1, "event_one", listen_one, propagate=True)
         event.listen(t1, "event_two", listen_two)
 
         t2 = Target()
-        
+
         t2.dispatch._update(t1.dispatch)
-        
+
         t2.dispatch.event_one(t2, 1)
         t2.dispatch.event_two(t2, 2)
         eq_(result, [(t2, 1)])
index d11644dbe8c3211124b7e7c0e06e73aab9817c13..845114447162b9519d381eac99504887dec4a982 100644 (file)
@@ -85,7 +85,7 @@ class FrozenDictTest(TestBase):
         d = util.frozendict({1:2, 3:4})
         for loads, dumps in picklers():
             print loads(dumps(d))
-        
+
 
 class MemoizedAttrTest(TestBase):
     def test_memoized_property(self):
@@ -96,7 +96,7 @@ class MemoizedAttrTest(TestBase):
                 v = val[0]
                 val[0] += 1
                 return v
-                
+
         ne_(Foo.bar, None)
         f1 = Foo()
         assert 'bar' not in f1.__dict__
@@ -120,7 +120,7 @@ class MemoizedAttrTest(TestBase):
         eq_(f1.bar(), 20)
         eq_(f1.bar(), 20)
         eq_(val[0], 21)
-        
+
 class ColumnCollectionTest(TestBase):
     def test_in(self):
         cc = sql.ColumnCollection()
@@ -151,7 +151,7 @@ class ColumnCollectionTest(TestBase):
 
 class LRUTest(TestBase):
 
-    def test_lru(self):                
+    def test_lru(self):
         class item(object):
             def __init__(self, id):
                 self.id = id
@@ -191,7 +191,7 @@ class LRUTest(TestBase):
         l[25] = i2
         assert 25 in l
         assert l[25] is i2
-        
+
 
 class ImmutableSubclass(str):
     pass
@@ -205,7 +205,7 @@ class FlattenIteratorTest(TestBase):
     def test_str_with_iter(self):
         """ensure that a str object with an __iter__ method (like in
         PyPy) is not interpreted as an iterable.
-        
+
         """
         class IterString(str):
             def __iter__(self):
@@ -214,7 +214,7 @@ class FlattenIteratorTest(TestBase):
         assert list(util.flatten_iterator([IterString('asdf'),
                     [IterString('x'), IterString('y')]])) == ['asdf',
                 'x', 'y']
-                
+
 class HashOverride(object):
     def __init__(self, value=None):
         self.value = value
@@ -235,7 +235,7 @@ class EqOverride(object):
             return self.value != other.value
         else:
             return True
-            
+
 class HashEqOverride(object):
     def __init__(self, value=None):
         self.value = value
@@ -371,7 +371,7 @@ class IdentitySetTest(TestBase):
         assert_raises(TypeError, lambda: s1 - [3, 4, 5])
 
 class OrderedIdentitySetTest(TestBase):
-    
+
     def assert_eq(self, identityset, expected_iterable):
         expected = [id(o) for o in expected_iterable]
         found = [id(o) for o in identityset]
@@ -386,10 +386,10 @@ class OrderedIdentitySetTest(TestBase):
     def test_intersection(self):
         elem = object
         eq_ = self.assert_eq
-        
+
         a, b, c, d, e, f, g = \
                 elem(), elem(), elem(), elem(), elem(), elem(), elem()
-        
+
         s1 = util.OrderedIdentitySet([a, b, c])
         s2 = util.OrderedIdentitySet([d, e, f])
         s3 = util.OrderedIdentitySet([a, d, f, g])
@@ -426,7 +426,7 @@ class DictlikeIteritemsTest(TestBase):
         d = UserDict.UserDict(a=1,b=2,c=3)
         self._ok(d)
     # end Py2K
-    
+
     def test_object(self):
         self._notok(object())
 
@@ -486,7 +486,7 @@ class DuckTypeCollectionTest(TestBase):
 
         class ForcedSet(list):
             __emulates__ = set
-        
+
         for type_ in (set,
                       # Py2K
                       sets.Set,
@@ -1043,7 +1043,7 @@ class TestClassHierarchy(TestBase):
 
         eq_(set(util.class_hierarchy(A)), set((A, B, C, object)))
         eq_(set(util.class_hierarchy(B)), set((A, B, C, object)))
-    
+
     # Py2K
     def test_oldstyle_mixin(self):
         class A(object):
@@ -1059,7 +1059,7 @@ class TestClassHierarchy(TestBase):
         eq_(set(util.class_hierarchy(Mixin)), set())
         eq_(set(util.class_hierarchy(A)), set((A, B, object)))
     # end Py2K
-        
+
 
 class TestClassProperty(TestBase):
 
index 5ffa8b89fd07a4593eafc2065a3222f9458ba0df..0303c84dba22c34190bddbcf0870947302a465ab 100644 (file)
@@ -26,7 +26,7 @@ class NoseSQLAlchemy(Plugin):
     Handles the setup and extra properties required for testing SQLAlchemy
     """
     enabled = True
-    
+
     # nose 1.0 will allow us to replace the old "sqlalchemy" plugin,
     # if installed, using the same name, but nose 1.0 isn't released yet...
     name = '_sqlalchemy'
@@ -79,33 +79,33 @@ class NoseSQLAlchemy(Plugin):
         file_config.readfp(StringIO.StringIO(base_config))
         file_config.read(['test.cfg', os.path.expanduser('~/.satest.cfg')])
         config.file_config = file_config
-        
+
     def configure(self, options, conf):
         Plugin.configure(self, options, conf)
         self.options = options
         for fn in pre_configure:
             fn(self.options, file_config)
-            
+
     def begin(self):
         global testing, requires, util
         from test.lib import testing, requires
         from sqlalchemy import util
-        
+
         testing.db = db
         testing.requires = requires
 
         # Lazy setup of other options (post coverage)
         for fn in post_configure:
             fn(self.options, file_config)
-        
+
     def describeTest(self, test):
         return ""
-    
+
     def wantFunction(self, fn):
         if fn.__module__.startswith('test.lib') or \
             fn.__module__.startswith('test.bootstrap'):
             return False
-            
+
     def wantClass(self, cls):
         """Return true if you want the main test selector to collect
         tests from this class, false if you don't, and None if you don't
@@ -124,7 +124,7 @@ class NoseSQLAlchemy(Plugin):
                 return True
             else:
                 return not self.__should_skip_for(cls)
-    
+
     def __should_skip_for(self, cls):
         if hasattr(cls, '__requires__'):
             def test_suite(): return 'ok'
@@ -141,13 +141,13 @@ class NoseSQLAlchemy(Plugin):
                 print "'%s' unsupported on DB implementation '%s'" % (
                      cls.__class__.__name__, testing.db.name)
                 return True
-                
+
         if getattr(cls, '__only_on__', None):
             spec = testing.db_spec(*util.to_list(cls.__only_on__))
             if not spec(testing.db):
                 print "'%s' unsupported on DB implementation '%s'" % (
                      cls.__class__.__name__, testing.db.name)
-                return True                    
+                return True
 
         if getattr(cls, '__skip_if__', False):
             for c in getattr(cls, '__skip_if__'):
@@ -155,7 +155,7 @@ class NoseSQLAlchemy(Plugin):
                     print "'%s' skipped by %s" % (
                         cls.__class__.__name__, c.__name__)
                     return True
-                    
+
         for rule in getattr(cls, '__excluded_on__', ()):
             if testing._is_excluded(*rule):
                 print "'%s' unsupported on DB %s version %s" % (
@@ -169,10 +169,10 @@ class NoseSQLAlchemy(Plugin):
 
     def afterTest(self, test):
         testing.resetwarnings()
-        
+
     def afterContext(self):
         testing.global_cleanup_assertions()
-        
+
     #def handleError(self, test, err):
         #pass
 
index 814c267b5cedd8093a85c5b7ee1a892f31d64e24..ce708936b7ffc8989985292931128ff688005278 100644 (file)
@@ -169,7 +169,7 @@ CREATE DOMAIN DOM_ID INTEGER NOT NULL
 CREATE TABLE A (
 ID DOM_ID /* INTEGER NOT NULL */ DEFAULT 0 )
 """
-    
+
     # the 'default' keyword is lower case here
     TABLE_B = """\
 CREATE TABLE B (
@@ -222,14 +222,14 @@ ID DOM_ID /* INTEGER NOT NULL */ default 0 )
         table_a = Table('a', metadata, autoload=True)
 
         eq_(table_a.c.id.server_default.arg.text, "0")
-    
+
     def test_lowercase_default_name(self):
         metadata = MetaData(testing.db)
 
         table_b = Table('b', metadata, autoload=True)
 
         eq_(table_b.c.id.server_default.arg.text, "0")
-        
+
 
 class CompileTest(TestBase, AssertsCompiledSQL):
 
index 68203cfea8ffd4c3ddd613aeba4bd1f7bdd0ab55..6cc3271514d78245f74c2f67ea86e8b75cce821b 100644 (file)
@@ -31,15 +31,15 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'UPDATE sometable SET somecolumn=:somecolum'
                             'n WHERE sometable.somecolumn = '
                             ':somecolumn_1', dict(somecolumn=10))
-    
+
     # TODO: should this be for *all* MS-SQL dialects ?
     def test_mxodbc_binds(self):
         """mxodbc uses MS-SQL native binds, which aren't allowed in
         various places."""
-        
+
         mxodbc_dialect = mxodbc.dialect()
         t = table('sometable', column('foo'))
-        
+
         for expr, compile in [
             (
                 select([literal("x"), literal("y")]), 
@@ -61,7 +61,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
             )
         ]:
             self.assert_compile(expr, compile, dialect=mxodbc_dialect)
-    
+
     def test_in_with_subqueries(self):
         """Test that when using subqueries in a binary expression
         the == and != are changed to IN and NOT IN respectively.
@@ -151,7 +151,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'remotetable_1.value FROM mytable JOIN '
                             'remote_owner.remotetable AS remotetable_1 '
                             'ON remotetable_1.rem_id = mytable.myid')
-        
+
         self.assert_compile(select([table4.c.rem_id,
                 table4.c.value]).apply_labels().union(select([table1.c.myid,
                 table1.c.description]).apply_labels()).alias().select(),
@@ -163,8 +163,8 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                 "SELECT mytable.myid AS mytable_myid, mytable.description "
                 "AS mytable_description FROM mytable) AS anon_1"
             )
-        
-        
+
+
     def test_delete_schema(self):
         metadata = MetaData()
         tbl = Table('test', metadata, Column('id', Integer,
@@ -337,9 +337,9 @@ class CompileTest(TestBase, AssertsCompiledSQL):
 
     def test_limit_using_top(self):
         t = table('t', column('x', Integer), column('y', Integer))
-        
+
         s = select([t]).where(t.c.x==5).order_by(t.c.y).limit(10)
-        
+
         self.assert_compile(
             s,
             "SELECT TOP 10 t.x, t.y FROM t WHERE t.x = :x_1 ORDER BY t.y",
@@ -348,9 +348,9 @@ class CompileTest(TestBase, AssertsCompiledSQL):
 
     def test_offset_using_window(self):
         t = table('t', column('x', Integer), column('y', Integer))
-        
+
         s = select([t]).where(t.c.x==5).order_by(t.c.y).offset(20)
-        
+
         self.assert_compile(
             s,
             "SELECT anon_1.x, anon_1.y FROM (SELECT t.x AS x, t.y "
@@ -362,9 +362,9 @@ class CompileTest(TestBase, AssertsCompiledSQL):
 
     def test_limit_offset_using_window(self):
         t = table('t', column('x', Integer), column('y', Integer))
-        
+
         s = select([t]).where(t.c.x==5).order_by(t.c.y).limit(10).offset(20)
-        
+
         self.assert_compile(
             s,
             "SELECT anon_1.x, anon_1.y "
@@ -375,9 +375,9 @@ class CompileTest(TestBase, AssertsCompiledSQL):
             "WHERE mssql_rn > :mssql_rn_1 AND mssql_rn <= :mssql_rn_2",
             {u'mssql_rn_1': 20, u'mssql_rn_2': 30, u'x_1': 5}
         )
-        
-        
-        
+
+
+
 class IdentityInsertTest(TestBase, AssertsCompiledSQL):
     __only_on__ = 'mssql'
     __dialect__ = mssql.MSDialect()
@@ -496,7 +496,7 @@ class ReflectionTest(TestBase, ComparesTables):
                                 and table2.c['col1'].default
         assert sequence.start == 2
         assert sequence.increment == 3
-    
+
     @testing.emits_warning("Did not recognize")
     @testing.provide_metadata
     def test_skip_types(self):
@@ -509,14 +509,14 @@ class ReflectionTest(TestBase, ComparesTables):
 
     @testing.provide_metadata
     def test_indexes_cols(self):
-        
+
         t1 = Table('t', metadata, Column('x', Integer), Column('y', Integer))
         Index('foo', t1.c.x, t1.c.y)
         metadata.create_all()
-        
+
         m2 = MetaData()
         t2 = Table('t', m2, autoload=True, autoload_with=testing.db)
-        
+
         eq_(
             set(list(t2.indexes)[0].columns),
             set([t2.c['x'], t2.c.y])
@@ -524,38 +524,38 @@ class ReflectionTest(TestBase, ComparesTables):
 
     @testing.provide_metadata
     def test_indexes_cols_with_commas(self):
-        
+
         t1 = Table('t', metadata, 
                         Column('x, col', Integer, key='x'), 
                         Column('y', Integer)
                     )
         Index('foo', t1.c.x, t1.c.y)
         metadata.create_all()
-        
+
         m2 = MetaData()
         t2 = Table('t', m2, autoload=True, autoload_with=testing.db)
-        
+
         eq_(
             set(list(t2.indexes)[0].columns),
             set([t2.c['x, col'], t2.c.y])
         )
-    
+
     @testing.provide_metadata
     def test_indexes_cols_with_spaces(self):
-        
+
         t1 = Table('t', metadata, Column('x col', Integer, key='x'), 
                                     Column('y', Integer))
         Index('foo', t1.c.x, t1.c.y)
         metadata.create_all()
-        
+
         m2 = MetaData()
         t2 = Table('t', m2, autoload=True, autoload_with=testing.db)
-        
+
         eq_(
             set(list(t2.indexes)[0].columns),
             set([t2.c['x col'], t2.c.y])
         )
-        
+
 class QueryUnicodeTest(TestBase):
 
     __only_on__ = 'mssql'
@@ -587,24 +587,24 @@ class QueryTest(TestBase):
     def test_fetchid_trigger(self):
         """
         Verify identity return value on inserting to a trigger table.
-        
+
         MSSQL's OUTPUT INSERTED clause does not work for the
         case of a table having an identity (autoincrement)
         primary key column, and which also has a trigger configured
         to fire upon each insert and subsequently perform an
         insert into a different table. 
-        
+
         SQLALchemy's MSSQL dialect by default will attempt to
         use an OUTPUT_INSERTED clause, which in this case will
         raise the following error:
-        
+
         ProgrammingError: (ProgrammingError) ('42000', 334, 
         "[Microsoft][SQL Server Native Client 10.0][SQL Server]The 
         target table 't1' of the DML statement cannot have any enabled
         triggers if the statement contains an OUTPUT clause without
         INTO clause.", 7748) 'INSERT INTO t1 (descr) OUTPUT inserted.id
         VALUES (?)' ('hello',)
-        
+
         This test verifies a workaround, which is to rely on the
         older SCOPE_IDENTITY() call, which still works for this scenario.
         To enable the workaround, the Table must be instantiated
@@ -759,10 +759,10 @@ class SchemaTest(TestBase):
         dialect = mssql.dialect()
         self.ddl_compiler = dialect.ddl_compiler(dialect,
                 schema.CreateTable(t))
-    
+
     def _column_spec(self):
         return self.ddl_compiler.get_column_specification(self.column)
-        
+
     def test_that_mssql_default_nullability_emits_null(self):
         eq_("test_column VARCHAR(max) NULL", self._column_spec())
 
@@ -998,7 +998,7 @@ class ParseConnectTest(TestBase, AssertsCompiledSQL):
         connection = dialect.create_connect_args(u)
         eq_([['DRIVER={SQL Server};Server=hostspec;Database=database;UI'
             'D=username;PWD=password'], {}], connection)
-    
+
     def test_pymssql_port_setting(self):
         dialect = pymssql.dialect()
 
@@ -1017,7 +1017,7 @@ class ParseConnectTest(TestBase, AssertsCompiledSQL):
             [[], {'host': 'somehost:5000', 'password': 'tiger', 
                     'user': 'scott', 'database': 'test'}], connection
         )
-    
+
     @testing.only_on(['mssql+pyodbc', 'mssql+pymssql'], "FreeTDS specific test")
     def test_bad_freetds_warning(self):
         engine = engines.testing_engine()
@@ -1040,7 +1040,7 @@ class TypesTest(TestBase, AssertsExecutionResults, ComparesTables):
 
     def teardown(self):
         metadata.drop_all()
-    
+
     @testing.fails_on_everything_except('mssql+pyodbc',
             'this is some pyodbc-specific feature')
     def test_decimal_notation(self):
@@ -1424,7 +1424,7 @@ class TypesTest(TestBase, AssertsExecutionResults, ComparesTables):
              'NCHAR(1)'),
             (mssql.MSNChar, [1], {'collation': 'Latin1_General_CI_AS'},
              'NCHAR(1) COLLATE Latin1_General_CI_AS'),
-             
+
             (mssql.MSString, [], {},
              'VARCHAR(max)'),
             (mssql.MSString, [1], {},
@@ -1535,7 +1535,7 @@ class TypesTest(TestBase, AssertsExecutionResults, ComparesTables):
                 elif c.name.startswith('int_n'):
                     assert not c.autoincrement, name
                     assert tbl._autoincrement_column is not c, name
-            
+
             # mxodbc can't handle scope_identity() with DEFAULT VALUES
 
             if testing.db.driver == 'mxodbc':
@@ -1548,7 +1548,7 @@ class TypesTest(TestBase, AssertsExecutionResults, ComparesTables):
                      : False}),
                      engines.testing_engine(options={'implicit_returning'
                      : True})]
-                    
+
             for counter, engine in enumerate(eng):
                 engine.execute(tbl.insert())
                 if 'int_y' in tbl.c:
@@ -1563,9 +1563,9 @@ class TypesTest(TestBase, AssertsExecutionResults, ComparesTables):
 
 class BinaryTest(TestBase, AssertsExecutionResults):
     """Test the Binary and VarBinary types"""
-    
+
     __only_on__ = 'mssql'
-    
+
     @classmethod
     def setup_class(cls):
         global binary_table, MyPickleType
@@ -1583,7 +1583,7 @@ class BinaryTest(TestBase, AssertsExecutionResults):
                     value.stuff = 'this is the right stuff'
                 return value
 
-        binary_table = Table(  
+        binary_table = Table(
             'binary_table',
             MetaData(testing.db),
             Column('primary_id', Integer, Sequence('binary_id_seq',
index 36cfc9b08202e15b73adbe71322a37f53f9bcd54..58ceaf91c1f89866448c6da61b86595fcfcc9d6b 100644 (file)
@@ -10,7 +10,7 @@ class MockDBAPI(object):
         self.log = []
     def connect(self, *args, **kwargs):
         return MockConnection(self)
-    
+
 class MockConnection(object):
     def __init__(self, parent):
         self.parent = parent
index 7d5cffbe260610460903a388506db25d8421e794..2fe9e7533101c335f6ecffd92002d5feff840e03 100644 (file)
@@ -19,7 +19,7 @@ class TypesTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
     __only_on__ = 'mysql'
     __dialect__ = mysql.dialect()
-    
+
     @testing.uses_deprecated('Manually quoting ENUM value literals')
     def test_basic(self):
         meta1 = MetaData(testing.db)
@@ -485,22 +485,22 @@ class TypesTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
             # if needed, can break out the eq_() just to check for
             # timestamps that are within a few seconds of "now" 
             # using timedelta.
-            
+
             now = testing.db.execute("select now()").scalar()
-            
+
             # TIMESTAMP without NULL inserts current time when passed
             # NULL.  when not passed, generates 0000-00-00 quite
             # annoyingly.
             ts_table.insert().execute({'t1':now, 't2':None})
             ts_table.insert().execute({'t1':None, 't2':None})
-            
+
             eq_(
                 ts_table.select().execute().fetchall(),
                 [(now, now), (None, now)]
             )
         finally:
             meta.drop_all()
-            
+
     def test_year(self):
         """Exercise YEAR."""
 
@@ -623,7 +623,7 @@ class TypesTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
         assert_raises(exc.SQLError, enum_table.insert().execute, 
                         e1=None, e2=None, e3=None, e4=None)
-        
+
         assert_raises(exc.InvalidRequestError, enum_table.insert().execute,
                                         e1='c', e2='c', e2generic='c', e3='c',
                                         e4='c', e5='c', e5generic='c', e6='c')
@@ -663,7 +663,7 @@ class TypesTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
         eq_(res, expected)
         enum_table.drop()
-    
+
     def test_unicode_enum(self):
         unicode_engine = utf8_engine()
         metadata = MetaData(unicode_engine)
@@ -696,7 +696,7 @@ class TypesTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
                     (u'réveillé', u'drôle') #, u'S’il') # eh ? 
         finally:
             metadata.drop_all()
-        
+
     def test_enum_compile(self):
         e1 = Enum('x', 'y', 'z', name='somename')
         t1 = Table('sometable', MetaData(), Column('somecolumn', e1))
@@ -709,7 +709,7 @@ class TypesTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
                             "CREATE TABLE sometable (somecolumn "
                             "VARCHAR(1), CHECK (somecolumn IN ('x', "
                             "'y', 'z')))")
-        
+
     @testing.exclude('mysql', '<', (4,), "3.23 can't handle an ENUM of ''")
     @testing.uses_deprecated('Manually quoting ENUM value literals')
     def test_enum_parse(self):
@@ -1041,7 +1041,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
         eq_(
             gen(True, ['high_priority', sql.text('sql_cache')]),
             'SELECT high_priority sql_cache DISTINCT q')
-        
+
     def test_backslash_escaping(self):
         self.assert_compile(
             sql.column('foo').like('bar', escape='\\'),
@@ -1055,7 +1055,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
             "foo LIKE %s ESCAPE '\\'",
             dialect=dialect
         )
-        
+
     def test_limit(self):
         t = sql.table('t', sql.column('col1'), sql.column('col2'))
 
@@ -1068,13 +1068,13 @@ class SQLTest(TestBase, AssertsCompiledSQL):
             select([t]).limit(10),
             "SELECT t.col1, t.col2 FROM t  LIMIT %s", 
             {'param_1':10})
-            
+
         self.assert_compile(
             select([t]).offset(10),
             "SELECT t.col1, t.col2 FROM t  LIMIT %s, 18446744073709551615",
             {'param_1':10}
             )
-    
+
     def test_varchar_raise(self):
         for type_ in (
             String,
@@ -1087,7 +1087,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
         ):
             type_ = sqltypes.to_instance(type_)
             assert_raises(exc.InvalidRequestError, type_.compile, dialect=mysql.dialect())
-            
+
     def test_update_limit(self):
         t = sql.table('t', sql.column('col1'), sql.column('col2'))
 
@@ -1113,7 +1113,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
 
     def test_sysdate(self):
         self.assert_compile(func.sysdate(), "SYSDATE()")
-        
+
     def test_cast(self):
         t = sql.table('t', sql.column('col'))
         m = mysql
@@ -1205,7 +1205,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
 
         for type_, expected in specs:
             self.assert_compile(cast(t.c.col, type_), expected)
-    
+
     def test_no_cast_pre_4(self):
         self.assert_compile(
                     cast(Column('foo', Integer), String),
@@ -1218,7 +1218,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
                     "foo",
                     dialect=dialect
             )
-        
+
     def test_extract(self):
         t = sql.table('t', sql.column('col1'))
 
@@ -1231,24 +1231,24 @@ class SQLTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(
             select([extract('milliseconds', t.c.col1)]),
             "SELECT EXTRACT(millisecond FROM t.col1) AS anon_1 FROM t")
-    
+
     def test_too_long_index(self):
         exp = 'ix_zyrenian_zyme_zyzzogeton_zyzzogeton_zyrenian_zyme_zyz_5cd2'
         tname = 'zyrenian_zyme_zyzzogeton_zyzzogeton'
         cname = 'zyrenian_zyme_zyzzogeton_zo'
-        
+
         t1 = Table(tname, MetaData(), 
                     Column(cname, Integer, index=True),
                 )
         ix1 = list(t1.indexes)[0]
-        
+
         self.assert_compile(
             schema.CreateIndex(ix1),
             "CREATE INDEX %s "
             "ON %s (%s)" % (exp, tname, cname),
             dialect=mysql.dialect()
         )
-        
+
     def test_innodb_autoincrement(self):
         t1 = Table('sometable', MetaData(), Column('assigned_id',
                    Integer(), primary_key=True, autoincrement=False),
@@ -1273,7 +1273,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
 
 class SQLModeDetectionTest(TestBase):
     __only_on__ = 'mysql'
-    
+
     def _options(self, modes):
         def connect(con, record):
             cursor = con.cursor()
@@ -1286,7 +1286,7 @@ class SQLModeDetectionTest(TestBase):
             ]
         })
         return e
-        
+
     def test_backslash_escapes(self):
         engine = self._options(['NO_BACKSLASH_ESCAPES'])
         c = engine.connect()
@@ -1314,7 +1314,7 @@ class SQLModeDetectionTest(TestBase):
         assert not engine.dialect._backslash_escapes
         c.close()
         engine.dispose()
-        
+
 class RawReflectionTest(TestBase):
     def setup(self):
         dialect = mysql.dialect()
@@ -1346,7 +1346,7 @@ class ExecutionTest(TestBase):
         meta.reflect(cx)
         eq_(cx.dialect._connection_charset, charset)
         cx.close()
-    
+
     def test_sysdate(self):
         d = testing.db.scalar(func.sysdate())
         assert isinstance(d, datetime.datetime)
@@ -1402,7 +1402,7 @@ class MatchTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(
             matchtable.c.title.match('somstr'),
             "MATCH (matchtable.title) AGAINST (%s IN BOOLEAN MODE)" % format)
-    
+
     @testing.fails_on('mysql+mysqldb', 'uses format')
     @testing.fails_on('mysql+oursql', 'uses format')
     @testing.fails_on('mysql+pyodbc', 'uses format')
index d842c7fc226b5aa7d8bdb914685f6819c2864835..a4c3f0a834d02fc81020b04d8bd45047a67d00e7 100644 (file)
@@ -120,7 +120,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'col2 FROM sometable ORDER BY '
                             'sometable.col2) WHERE ROWNUM <= :ROWNUM_1 '
                             'FOR UPDATE')
-        
+
         s = select([t],
                    for_update=True).limit(10).offset(20).order_by(t.c.col2)
         self.assert_compile(s,
@@ -131,14 +131,14 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'sometable.col2) WHERE ROWNUM <= '
                             ':ROWNUM_1) WHERE ora_rn > :ora_rn_1 FOR '
                             'UPDATE')
-        
-    
+
+
     def test_long_labels(self):
         dialect = default.DefaultDialect()
         dialect.max_identifier_length = 30
-        
+
         ora_dialect = oracle.dialect()
-        
+
         m = MetaData()
         a_table = Table(
             'thirty_characters_table_xxxxxx',
@@ -156,7 +156,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                 primary_key=True
             )
         )
-        
+
         anon = a_table.alias()
         self.assert_compile(select([other_table,
                             anon]).
@@ -189,7 +189,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'thirty_characters_table__1.id = '
                             'other_thirty_characters_table_.thirty_char'
                             'acters_table_id', dialect=ora_dialect)
-        
+
     def test_outer_join(self):
         table1 = table('mytable',
             column('myid', Integer),
@@ -283,12 +283,12 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'mytable.name) WHERE ROWNUM <= :ROWNUM_1) '
                             'WHERE ora_rn > :ora_rn_1',
                             dialect=oracle.dialect(use_ansi=False))
-                            
+
         subq = select([table1]).select_from(table1.outerjoin(table2,
                 table1.c.myid == table2.c.otherid)).alias()
         q = select([table3]).select_from(table3.outerjoin(subq,
                 table3.c.userid == subq.c.myid))
-                
+
         self.assert_compile(q,
                             'SELECT thirdtable.userid, '
                             'thirdtable.otherstuff FROM thirdtable '
@@ -299,7 +299,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'mytable.myid = myothertable.otherid) '
                             'anon_1 ON thirdtable.userid = anon_1.myid'
                             , dialect=oracle.dialect(use_ansi=True))
-                            
+
         self.assert_compile(q,
                             'SELECT thirdtable.userid, '
                             'thirdtable.otherstuff FROM thirdtable, '
@@ -310,7 +310,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             '+)) anon_1 WHERE thirdtable.userid = '
                             'anon_1.myid(+)',
                             dialect=oracle.dialect(use_ansi=False))
-                            
+
         q = select([table1.c.name]).where(table1.c.name == 'foo')
         self.assert_compile(q,
                             'SELECT mytable.name FROM mytable WHERE '
@@ -326,7 +326,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'mytable.name) AS bar FROM mytable',
                             dialect=oracle.dialect(use_ansi=False))
 
-        
+
     def test_alias_outer_join(self):
         address_types = table('address_types', column('id'),
                               column('name'))
@@ -362,11 +362,11 @@ class CompileTest(TestBase, AssertsCompiledSQL):
 
 class CompatFlagsTest(TestBase, AssertsCompiledSQL):
     __only_on__ = 'oracle'
-    
+
     def test_ora8_flags(self):
         def server_version_info(self):
             return (8, 2, 5)
-            
+
         dialect = oracle.dialect(dbapi=testing.db.dialect.dbapi)
         dialect._get_server_version_info = server_version_info
 
@@ -389,7 +389,7 @@ class CompatFlagsTest(TestBase, AssertsCompiledSQL):
         dialect._get_server_version_info = server_version_info
         dialect.initialize(testing.db.connect())
         assert dialect.implicit_returning
-        
+
 
     def test_default_flags(self):
         """test with no initialization or server version info"""
@@ -400,7 +400,7 @@ class CompatFlagsTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(String(50),"VARCHAR(50 CHAR)",dialect=dialect)
         self.assert_compile(Unicode(50),"NVARCHAR2(50)",dialect=dialect)
         self.assert_compile(UnicodeText(),"NCLOB",dialect=dialect)
-    
+
     def test_ora10_flags(self):
         def server_version_info(self):
             return (10, 2, 5)
@@ -413,23 +413,23 @@ class CompatFlagsTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(String(50),"VARCHAR(50 CHAR)",dialect=dialect)
         self.assert_compile(Unicode(50),"NVARCHAR2(50)",dialect=dialect)
         self.assert_compile(UnicodeText(),"NCLOB",dialect=dialect)
-    
-    
+
+
 class MultiSchemaTest(TestBase, AssertsCompiledSQL):
     __only_on__ = 'oracle'
-    
+
     @classmethod
     def setup_class(cls):
         # currently assuming full DBA privs for the user.
         # don't really know how else to go here unless
         # we connect as the other user.
-        
+
         for stmt in """
 create table test_schema.parent(
     id integer primary key, 
     data varchar2(50)
 );
-                
+
 create table test_schema.child(
     id integer primary key,
     data varchar2(50), 
@@ -441,14 +441,14 @@ create synonym test_schema.ctable for test_schema.child;
 
 -- can't make a ref from local schema to the 
 -- remote schema's table without this, 
--- *and* cant give yourself a grant !  
+-- *and* cant give yourself a grant !
 -- so we give it to public.  ideas welcome. 
 grant references on test_schema.parent to public;
 grant references on test_schema.child to public;
 """.split(";"):
             if stmt.strip():
                 testing.db.execute(stmt)
-        
+
     @classmethod
     def teardown_class(cls):
         for stmt in """
@@ -459,7 +459,7 @@ drop synonym test_schema.ptable;
 """.split(";"):
             if stmt.strip():
                 testing.db.execute(stmt)
-        
+
     def test_create_same_names_explicit_schema(self):
         schema = testing.db.dialect.default_schema_name
         meta = MetaData(testing.db)
@@ -597,7 +597,7 @@ class ConstraintTest(TestBase):
                     ForeignKeyConstraint(['foo_id'], ['foo.id'],
                     onupdate='CASCADE'))
         assert_raises(exc.SAWarning, bat.create)
-        
+
 class TypesTest(TestBase, AssertsCompiledSQL):
     __only_on__ = 'oracle'
     __dialect__ = oracle.OracleDialect()
@@ -620,7 +620,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
 
         b = bindparam("foo", u"hello world!")
         assert b.type.dialect_impl(dialect).get_dbapi_type(dbapi) == 'STRING'
-    
+
     @testing.fails_on('+zxjdbc', 'zxjdbc lacks the FIXED_CHAR dbapi type')
     def test_fixed_char(self):
         m = MetaData(testing.db)
@@ -628,7 +628,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             Column('id', Integer, primary_key=True),
             Column('data', CHAR(30), nullable=False)
         )
-        
+
         t.create()
         try:
             t.insert().execute(
@@ -640,17 +640,17 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             eq_(t.select().where(t.c.data=='value 2').execute().fetchall(), 
                 [(2, 'value 2                       ')]
                 )
-                
+
             m2 = MetaData(testing.db)
             t2 = Table('t1', m2, autoload=True)
             assert type(t2.c.data.type) is CHAR
             eq_(t2.select().where(t2.c.data=='value 2').execute().fetchall(), 
                 [(2, 'value 2                       ')]
                 )
-            
+
         finally:
             t.drop()
-        
+
     def test_type_adapt(self):
         dialect = cx_oracle.dialect()
 
@@ -686,7 +686,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             assert isinstance(x, int)
         finally:
             t1.drop()
-    
+
     @testing.provide_metadata
     def test_rowid(self):
         t = Table('t1', metadata,
@@ -697,7 +697,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
         s1 = select([t])
         s2 = select([column('rowid')]).select_from(s1)
         rowid = s2.scalar()
-        
+
         # the ROWID type is not really needed here,
         # as cx_oracle just treats it as a string,
         # but we want to make sure the ROWID works...
@@ -707,7 +707,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
         eq_(s3.select().execute().fetchall(),
         [(5, rowid)]
         )
-        
+
     @testing.fails_on('+zxjdbc',
                       'Not yet known how to pass values of the '
                       'INTERVAL type')
@@ -738,7 +738,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
                 seconds=5743))
         finally:
             metadata.drop_all()
-        
+
     def test_numerics(self):
         m = MetaData(testing.db)
         t1 = Table('t1', m, 
@@ -750,7 +750,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             Column('numbercol1', oracle.NUMBER(9)),
             Column('numbercol2', oracle.NUMBER(9, 3)),
             Column('numbercol3', oracle.NUMBER),
-            
+
         )
         t1.create()
         try:
@@ -764,7 +764,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
                 numbercol2=14.85,
                 numbercol3=15.76
                 )
-            
+
             m2 = MetaData(testing.db)
             t2 = Table('t1', m2, autoload=True)
 
@@ -788,17 +788,17 @@ class TypesTest(TestBase, AssertsCompiledSQL):
 
         finally:
             t1.drop()
-    
+
     @testing.provide_metadata
     def test_numerics_broken_inspection(self):
         """Numeric scenarios where Oracle type info is 'broken',
         returning us precision, scale of the form (0, 0) or (0, -127).
         We convert to Decimal and let int()/float() processors take over.
-        
+
         """
-        
+
         # this test requires cx_oracle 5
-        
+
         foo = Table('foo', metadata,
             Column('idata', Integer),
             Column('ndata', Numeric(20, 2)),
@@ -807,7 +807,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             Column('fdata', Float()),
         )
         foo.create()
-        
+
         foo.insert().execute(
             {'idata':5, 'ndata':decimal.Decimal("45.6"), 'ndata2':decimal.Decimal("45.0"), 
                     'nidata':decimal.Decimal('53'), 'fdata':45.68392},
@@ -822,8 +822,8 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             fdata
         FROM foo
         """
-        
-        
+
+
         row = testing.db.execute(stmt).fetchall()[0]
         eq_([type(x) for x in row], [int, decimal.Decimal, decimal.Decimal, int, float])
         eq_(
@@ -857,7 +857,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             row, 
             (5, decimal.Decimal('45.6'), 45, 53, decimal.Decimal('45.68392'))
         )
-        
+
         row = testing.db.execute(text(stmt, 
                                 typemap={
                                         'idata':Integer(), 
@@ -870,7 +870,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
         eq_(row, 
             (5, decimal.Decimal('45.6'), decimal.Decimal('45'), decimal.Decimal('53'), 45.683920000000001)
         )
-        
+
         stmt = """
         SELECT 
                 anon_1.idata AS anon_1_idata,
@@ -924,7 +924,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             (5, 45.6, 45, 53, decimal.Decimal('45.68392'))
         )
 
-        
+
     def test_reflect_dates(self):
         metadata = MetaData(testing.db)
         Table(
@@ -946,10 +946,10 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             assert isinstance(t1.c.d3.type, TIMESTAMP)
             assert t1.c.d3.type.timezone
             assert isinstance(t1.c.d4.type, oracle.INTERVAL)
-            
+
         finally:
             metadata.drop_all()
-        
+
     def test_reflect_raw(self):
         types_table = Table('all_types', MetaData(testing.db),
             Column('owner', String(30), primary_key=True),
@@ -984,7 +984,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             assert isinstance(res, unicode)
         finally:
             metadata.drop_all()
-       
+
     def test_char_length(self):
         self.assert_compile(VARCHAR(50),"VARCHAR(50 CHAR)")
 
@@ -994,7 +994,7 @@ class TypesTest(TestBase, AssertsCompiledSQL):
 
         self.assert_compile(NVARCHAR(50),"NVARCHAR2(50)")
         self.assert_compile(CHAR(50),"CHAR(50)")
-        
+
         metadata = MetaData(testing.db)
         t1 = Table('t1', metadata,
               Column("c1", VARCHAR(50)),
@@ -1043,24 +1043,24 @@ class TypesTest(TestBase, AssertsCompiledSQL):
             eq_(row['bindata'].read(), 'this is binary')
         finally:
             t.drop(engine)
-            
+
 class EuroNumericTest(TestBase):
     """test the numeric output_type_handler when using non-US locale for NLS_LANG."""
-    
+
     __only_on__ = 'oracle+cx_oracle'
-    
+
     def setup(self):
         self.old_nls_lang = os.environ.get('NLS_LANG', False)
         os.environ['NLS_LANG'] = "GERMAN"
         self.engine = testing_engine()
-        
+
     def teardown(self):
         if self.old_nls_lang is not False:
             os.environ['NLS_LANG'] = self.old_nls_lang
         else:
             del os.environ['NLS_LANG']
         self.engine.dispose()
-        
+
     @testing.provide_metadata
     def test_output_type_handler(self):
         for stmt, exp, kw in [
@@ -1076,8 +1076,8 @@ class EuroNumericTest(TestBase):
                 exp
             )
             assert type(test_exp) is type(exp)
-        
-    
+
+
 class DontReflectIOTTest(TestBase):
     """test that index overflow tables aren't included in
     table_names."""
@@ -1097,10 +1097,10 @@ class DontReflectIOTTest(TestBase):
             PCTTHRESHOLD 20
             OVERFLOW TABLESPACE users
         """)
-    
+
     def teardown(self):
         testing.db.execute("drop table admin_docindex")
-    
+
     def test_reflect_all(self):
         m = MetaData(testing.db)
         m.reflect()
@@ -1108,7 +1108,7 @@ class DontReflectIOTTest(TestBase):
             set(t.name for t in m.tables.values()),
             set(['admin_docindex'])
         )
-        
+
 class BufferedColumnTest(TestBase, AssertsCompiledSQL):
     __only_on__ = 'oracle'
 
@@ -1145,7 +1145,7 @@ class BufferedColumnTest(TestBase, AssertsCompiledSQL):
 
 class UnsupportedIndexReflectTest(TestBase):
     __only_on__ = 'oracle'
-    
+
     def setup(self):
         global metadata
         metadata = MetaData(testing.db)
@@ -1153,16 +1153,16 @@ class UnsupportedIndexReflectTest(TestBase):
                     Column('data', String(20), primary_key=True)
                 )
         metadata.create_all()
-    
+
     def teardown(self):
         metadata.drop_all()
-        
+
     def test_reflect_functional_index(self):
         testing.db.execute('CREATE INDEX DATA_IDX ON '
                            'TEST_INDEX_REFLECT (UPPER(DATA))')
         m2 = MetaData(testing.db)
         t2 = Table('test_index_reflect', m2, autoload=True)
-    
+
 class RoundTripIndexTest(TestBase):
     __only_on__ = 'oracle'
 
@@ -1236,7 +1236,7 @@ class RoundTripIndexTest(TestBase):
             metadata.drop_all()
 
 
-        
+
 class SequenceTest(TestBase, AssertsCompiledSQL):
 
     def test_basic(self):
@@ -1250,8 +1250,8 @@ class SequenceTest(TestBase, AssertsCompiledSQL):
         seq = Sequence('My_Seq', schema='Some_Schema')
         assert dialect.identifier_preparer.format_sequence(seq) \
             == '"Some_Schema"."My_Seq"'
-    
-    
+
+
 class ExecuteTest(TestBase):
 
     __only_on__ = 'oracle'
@@ -1259,7 +1259,7 @@ class ExecuteTest(TestBase):
     def test_basic(self):
         eq_(testing.db.execute('/*+ this is a comment */ SELECT 1 FROM '
             'DUAL').fetchall(), [(1, )])
-    
+
     def test_sequences_are_integers(self):
         seq = Sequence('foo_seq')
         seq.create(testing.db)
@@ -1269,17 +1269,17 @@ class ExecuteTest(TestBase):
             assert type(val) is int
         finally:
             seq.drop(testing.db)
-            
+
     @testing.provide_metadata
     def test_limit_offset_for_update(self):
         # oracle can't actually do the ROWNUM thing with FOR UPDATE
         # very well.
-        
+
         t = Table('t1', metadata, Column('id', Integer, primary_key=True),
             Column('data', Integer)
         )
         metadata.create_all()
-        
+
         t.insert().execute(
             {'id':1, 'data':1},
             {'id':2, 'data':7},
@@ -1287,7 +1287,7 @@ class ExecuteTest(TestBase):
             {'id':4, 'data':15},
             {'id':5, 'data':32},
         )
-        
+
         # here, we can't use ORDER BY.
         eq_(
             t.select(for_update=True).limit(2).execute().fetchall(),
@@ -1302,5 +1302,5 @@ class ExecuteTest(TestBase):
             "ORA-02014",
             t.select(for_update=True).limit(2).offset(3).execute
         )
-        
-        
+
+
index cfccb9bb1c2cca06c16bc489537d0cd99010e437..a8c63c566b70a6d0763d20dabf76df06eb43d1c1 100644 (file)
@@ -56,7 +56,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'RETURNING length(mytable.name) AS length_1'
                             , dialect=dialect)
 
-        
+
     def test_insert_returning(self):
         dialect = postgresql.dialect()
         table1 = table('mytable',
@@ -83,7 +83,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'INSERT INTO mytable (name) VALUES '
                             '(%(name)s) RETURNING length(mytable.name) '
                             'AS length_1', dialect=dialect)
-    
+
     @testing.uses_deprecated('.*argument is deprecated.  Please use '
                              'statement.returning.*')
     def test_old_returning_names(self):
@@ -109,7 +109,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             'INSERT INTO mytable (name) VALUES '
                             '(%(name)s) RETURNING mytable.myid, '
                             'mytable.name', dialect=dialect)
-        
+
     def test_create_partial_index(self):
         m = MetaData()
         tbl = Table('testtbl', m, Column('data', Integer))
@@ -228,7 +228,7 @@ class FloatCoercionTest(TablesTest, AssertsExecutionResults):
             {'data':52},
             {'data':9},
         )
-    
+
     @testing.resolve_artifact_names
     def test_float_coercion(self):
         for type_, result in [
@@ -251,7 +251,7 @@ class FloatCoercionTest(TablesTest, AssertsExecutionResults):
                 ])
             ).scalar()
             eq_(round_decimal(ret, 9), result)
-    
+
     @testing.provide_metadata
     def test_arrays(self):
         t1 = Table('t', metadata, 
@@ -267,7 +267,7 @@ class FloatCoercionTest(TablesTest, AssertsExecutionResults):
             row, 
             ([5], [5], [6], [decimal.Decimal("6.4")])
         )
-        
+
 class EnumTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
     __only_on__ = 'postgresql'
@@ -296,7 +296,7 @@ class EnumTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
                             "CREATE TABLE sometable (somecolumn "
                             "VARCHAR(1), CHECK (somecolumn IN ('x', "
                             "'y', 'z')))")
-    
+
     @testing.fails_on('postgresql+zxjdbc',
                       'zxjdbc fails on ENUM: column "XXX" is of type '
                       'XXX but expression is of type character varying')
@@ -319,7 +319,7 @@ class EnumTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
         finally:
             metadata.drop_all()
             metadata.drop_all()
-    
+
     def test_name_required(self):
         metadata = MetaData(testing.db)
         etype = Enum('four', 'five', 'six', metadata=metadata)
@@ -341,7 +341,7 @@ class EnumTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
                     Enum(u'réveillé', u'drôle', u'S’il',
                             name='onetwothreetype'))
         )
-        
+
         metadata.create_all()
         try:
             t1.insert().execute(value=u'drôle')
@@ -411,24 +411,24 @@ class EnumTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
             metadata.drop_all()
             assert not testing.db.dialect.has_type(testing.db,
                     'fourfivesixtype')
-    
+
     def test_no_support(self):
         def server_version_info(self):
             return (8, 2)
-            
+
         e = engines.testing_engine()
         dialect = e.dialect
         dialect._get_server_version_info = server_version_info
-        
+
         assert dialect.supports_native_enum
         e.connect()
         assert not dialect.supports_native_enum
-        
+
         # initialize is called again on new pool
         e.dispose()
         e.connect()
         assert not dialect.supports_native_enum
-        
+
 
     def test_reflection(self):
         metadata = MetaData(testing.db)
@@ -476,14 +476,14 @@ class EnumTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
             metadata.drop_all()
 
 class NumericInterpretationTest(TestBase):
-    
-    
+
+
     def test_numeric_codes(self):
         from sqlalchemy.dialects.postgresql import pg8000, psycopg2, base
         from sqlalchemy.util.compat import decimal
-        
+
         for dialect in (pg8000.dialect(), psycopg2.dialect()):
-            
+
             typ = Numeric().dialect_impl(dialect)
             for code in base._INT_TYPES + base._FLOAT_TYPES + \
                         base._DECIMAL_TYPES:
@@ -492,7 +492,7 @@ class NumericInterpretationTest(TestBase):
                 if proc is not None:
                     val = proc(val)
                 assert val in (23.7, decimal.Decimal("23.7"))
-    
+
 class InsertTest(TestBase, AssertsExecutionResults):
 
     __only_on__ = 'postgresql'
@@ -540,7 +540,7 @@ class InsertTest(TestBase, AssertsExecutionResults):
             assert_raises_message(exc.DBAPIError,
                                   'violates not-null constraint',
                                   eng.execute, t2.insert())
-        
+
     def test_sequence_insert(self):
         table = Table('testtable', metadata, Column('id', Integer,
                       Sequence('my_seq'), primary_key=True),
@@ -975,7 +975,7 @@ class DomainReflectionTest(TestBase, AssertsExecutionResults):
         con.execute("DROP TABLE enum_test")
         con.execute("DROP DOMAIN enumdomain")
         con.execute("DROP TYPE testtype")
-        
+
     def test_table_is_reflected(self):
         metadata = MetaData(testing.db)
         table = Table('testtable', metadata, autoload=True)
@@ -990,7 +990,7 @@ class DomainReflectionTest(TestBase, AssertsExecutionResults):
             "Reflected default value didn't equal expected value")
         assert not table.columns.answer.nullable, \
             'Expected reflected column to not be nullable.'
-    
+
     def test_enum_domain_is_reflected(self):
         metadata = MetaData(testing.db)
         table = Table('enum_test', metadata, autoload=True)
@@ -998,7 +998,7 @@ class DomainReflectionTest(TestBase, AssertsExecutionResults):
             table.c.data.type.enums,
             ('test', )
         )
-        
+
     def test_table_is_reflected_test_schema(self):
         metadata = MetaData(testing.db)
         table = Table('testtable', metadata, autoload=True,
@@ -1356,7 +1356,7 @@ class MiscTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
                 'Skipped unsupported reflection of '
                 'expression-based index idx3'
             ])
-        
+
 
     @testing.fails_on('postgresql+pypostgresql',
                       'pypostgresql bombs on multiple calls')
@@ -1370,7 +1370,7 @@ class MiscTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
                             isolation_level='SERIALIZABLE')
         eq_(eng.execute('show transaction isolation level').scalar(),
             'serializable')
-        
+
         # check that it stays
         conn = eng.connect()
         eq_(conn.execute('show transaction isolation level').scalar(),
@@ -1381,7 +1381,7 @@ class MiscTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
         eq_(conn.execute('show transaction isolation level').scalar(),
             'serializable')
         conn.close()
-        
+
         eng = create_engine(testing.db.url, isolation_level='FOO')
         if testing.db.driver == 'zxjdbc':
             exception_cls = eng.dialect.dbapi.Error
@@ -1399,11 +1399,11 @@ class MiscTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
         stmt = text("select cast('hi' as char) as hi", typemap={'hi'
                     : Numeric})
         assert_raises(exc.InvalidRequestError, testing.db.execute, stmt)
-        
+
 class TimezoneTest(TestBase):
 
     """Test timezone-aware datetimes.
-    
+
     psycopg will return a datetime with a tzinfo attached to it, if
     postgresql returns it.  python then will not let you compare a
     datetime with a tzinfo to a datetime that doesnt have one.  this
@@ -1526,7 +1526,7 @@ class TimePrecisionTest(TestBase, AssertsCompiledSQL):
             eq_(t2.c.c6.type.timezone, True)
         finally:
             t1.drop()
-        
+
 class ArrayTest(TestBase, AssertsExecutionResults):
 
     __only_on__ = 'postgresql'
@@ -1654,7 +1654,7 @@ class ArrayTest(TestBase, AssertsExecutionResults):
         foo.id = 2
         sess.add(foo)
         sess.flush()
-    
+
     @testing.provide_metadata
     def test_tuple_flag(self):
         assert_raises_message(
@@ -1662,7 +1662,7 @@ class ArrayTest(TestBase, AssertsExecutionResults):
             "mutable must be set to False if as_tuple is True.",
             postgresql.ARRAY, Integer, mutable=True, 
                 as_tuple=True)
-        
+
         t1 = Table('t1', metadata,
             Column('id', Integer, primary_key=True),
             Column('data', postgresql.ARRAY(String(5), as_tuple=True, mutable=False)),
@@ -1672,7 +1672,7 @@ class ArrayTest(TestBase, AssertsExecutionResults):
         testing.db.execute(t1.insert(), id=1, data=["1","2","3"], data2=[5.4, 5.6])
         testing.db.execute(t1.insert(), id=2, data=["4", "5", "6"], data2=[1.0])
         testing.db.execute(t1.insert(), id=3, data=[["4", "5"], ["6", "7"]], data2=[[5.4, 5.6], [1.0, 1.1]])
-        
+
         r = testing.db.execute(t1.select().order_by(t1.c.id)).fetchall()
         eq_(
             r, 
@@ -1687,16 +1687,16 @@ class ArrayTest(TestBase, AssertsExecutionResults):
             set(row[1] for row in r),
             set([('1', '2', '3'), ('4', '5', '6'), (('4', '5'), ('6', '7'))])
         )
-        
-        
-        
+
+
+
 class TimestampTest(TestBase, AssertsExecutionResults):
     __only_on__ = 'postgresql'
 
     def test_timestamp(self):
         engine = testing.db
         connection = engine.connect()
-        
+
         s = select(["timestamp '2007-12-25'"])
         result = connection.execute(s).first()
         eq_(result[0], datetime.datetime(2007, 12, 25, 0, 0))
@@ -1846,15 +1846,15 @@ class ServerSideCursorsTest(TestBase, AssertsExecutionResults):
 
 class SpecialTypesTest(TestBase, ComparesTables):
     """test DDL and reflection of PG-specific types """
-    
+
     __only_on__ = 'postgresql'
     __excluded_on__ = (('postgresql', '<', (8, 3, 0)),)
-    
+
     @classmethod
     def setup_class(cls):
         global metadata, table
         metadata = MetaData(testing.db)
-        
+
         # create these types so that we can issue
         # special SQL92 INTERVAL syntax
         class y2m(types.UserDefinedType, postgresql.INTERVAL):
@@ -1864,7 +1864,7 @@ class SpecialTypesTest(TestBase, ComparesTables):
         class d2s(types.UserDefinedType, postgresql.INTERVAL):
             def get_col_spec(self):
                 return "INTERVAL DAY TO SECOND"
-            
+
         table = Table('sometable', metadata,
             Column('id', postgresql.PGUuid, primary_key=True),
             Column('flag', postgresql.PGBit),
@@ -1877,31 +1877,31 @@ class SpecialTypesTest(TestBase, ComparesTables):
             Column('month_interval', d2s()),
             Column('precision_interval', postgresql.INTERVAL(precision=3))
         )
-        
+
         metadata.create_all()
-        
+
         # cheat so that the "strict type check"
         # works
         table.c.year_interval.type = postgresql.INTERVAL()
         table.c.month_interval.type = postgresql.INTERVAL()
-    
+
     @classmethod
     def teardown_class(cls):
         metadata.drop_all()
-    
+
     def test_reflection(self):
         m = MetaData(testing.db)
         t = Table('sometable', m, autoload=True)
-        
+
         self.assert_tables_equal(table, t, strict_types=True)
         assert t.c.plain_interval.type.precision is None
         assert t.c.precision_interval.type.precision == 3
 
 class UUIDTest(TestBase):
     """Test the bind/return values of the UUID type."""
-    
+
     __only_on__ = 'postgresql'
-    
+
     @testing.requires.python25
     @testing.fails_on('postgresql+pg8000', 'No support for UUID type')
     def test_uuid_string(self):
@@ -1913,7 +1913,7 @@ class UUIDTest(TestBase):
             str(uuid.uuid4()),
             str(uuid.uuid4())
         )
-        
+
     @testing.requires.python25
     @testing.fails_on('postgresql+pg8000', 'No support for UUID type')
     def test_uuid_uuid(self):
@@ -1925,7 +1925,7 @@ class UUIDTest(TestBase):
             uuid.uuid4(),
             uuid.uuid4()
         )
-    
+
     def test_no_uuid_available(self):
         from sqlalchemy.dialects.postgresql import base
         uuid_type = base._python_UUID
@@ -1937,14 +1937,14 @@ class UUIDTest(TestBase):
             )
         finally:
             base._python_UUID = uuid_type
-        
+
     def setup(self):
         self.conn = testing.db.connect()
         trans = self.conn.begin()
-        
+
     def teardown(self):
         self.conn.close()
-        
+
     def _test_round_trip(self, utable, value1, value2):
         utable.create(self.conn)
         self.conn.execute(utable.insert(), {'data':value1})
@@ -1955,8 +1955,8 @@ class UUIDTest(TestBase):
                 )
         eq_(r.fetchone()[0], value2)
         eq_(r.fetchone(), None)
-        
-        
+
+
 class MatchTest(TestBase, AssertsCompiledSQL):
 
     __only_on__ = 'postgresql'
@@ -2063,9 +2063,9 @@ class MatchTest(TestBase, AssertsCompiledSQL):
 
 class TupleTest(TestBase):
     __only_on__ = 'postgresql'
-    
+
     def test_tuple_containment(self):
-        
+
         for test, exp in [
             ([('a', 'b')], True),
             ([('a', 'c')], False),
index 34f5927edfc7d6d5d8f1c9ee1d003605e1018208..e3618f841109df6e40fceb8d2d1dd658cecd205c 100644 (file)
@@ -16,7 +16,7 @@ class TestTypes(TestBase, AssertsExecutionResults):
 
     def test_boolean(self):
         """Test that the boolean only treats 1 as True
-        
+
         """
 
         meta = MetaData(testing.db)
@@ -214,7 +214,7 @@ class DialectTest(TestBase, AssertsExecutionResults):
 
     def test_extra_reserved_words(self):
         """Tests reserved words in identifiers.
-        
+
         'true', 'false', and 'column' are undocumented reserved words
         when used as column identifiers (as of 3.5.1).  Covering them
         here to ensure they remain in place if the dialect's
@@ -318,18 +318,18 @@ class DialectTest(TestBase, AssertsExecutionResults):
             except exc.DBAPIError:
                 pass
             raise
-        
+
     def test_pool_class(self):
         e = create_engine('sqlite+pysqlite://')
         assert e.pool.__class__ is pool.SingletonThreadPool
 
         e = create_engine('sqlite+pysqlite:///:memory:')
         assert e.pool.__class__ is pool.SingletonThreadPool
-        
+
         e = create_engine('sqlite+pysqlite:///foo.db')
         assert e.pool.__class__ is pool.NullPool
-        
-        
+
+
     def test_dont_reflect_autoindex(self):
         meta = MetaData(testing.db)
         t = Table('foo', meta, Column('bar', String, primary_key=True))
@@ -414,7 +414,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
                         Column('id', Integer, primary_key=True),
                         Column('t1_id', Integer, ForeignKey('master.t1.id')),
                     )
-        
+
         # schema->schema, generate REFERENCES with no schema name
         self.assert_compile(
             schema.CreateTable(t2),
@@ -423,7 +423,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
                 "t1_id INTEGER, "
                 "PRIMARY KEY (id), "
                 "FOREIGN KEY(t1_id) REFERENCES t1 (id)"
-                ")"            
+                ")"
         )
 
         # schema->different schema, don't generate REFERENCES
@@ -433,7 +433,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
                 "id INTEGER NOT NULL, "
                 "t1_id INTEGER, "
                 "PRIMARY KEY (id)"
-                ")"            
+                ")"
         )
 
         # same for local schema
@@ -443,7 +443,7 @@ class SQLTest(TestBase, AssertsCompiledSQL):
                 "id INTEGER NOT NULL, "
                 "t1_id INTEGER, "
                 "PRIMARY KEY (id)"
-                ")"            
+                ")"
         )
 
 
index 773fa2fea56662cd88ad6162b22815392c7cf379..b55ffcadb12eb7a7cfd2e0cbcf2512251f519a2b 100644 (file)
@@ -155,13 +155,13 @@ class AltEngineTest(testing.TestBase):
     def setup_class(cls):
         cls.engine = cls.create_engine()
         super(AltEngineTest, cls).setup_class()
-        
+
     @classmethod
     def teardown_class(cls):
         cls.engine.dispose()
         cls.engine = None
         super(AltEngineTest, cls).teardown_class()
-        
+
     @classmethod
     def create_engine(cls):
         raise NotImplementedError
index fbe77b9dc75bb4f21f691e322450867dcb86e445..c3914ab37c20fe7ce60e73cd02cd98ca8f250910 100644 (file)
@@ -72,7 +72,7 @@ class DDLEventTest(TestBase):
         canary = self.Canary(table, bind)
         event.listen(table, 'before_create', canary.before_create)
         event.listen(table, 'after_create', canary.after_create)
-        
+
         table.create(bind)
         assert canary.state == 'after-create'
         table.drop(bind)
@@ -151,7 +151,7 @@ class DDLEventTest(TestBase):
     def test_metadata_create_both(self):
         metadata, bind = self.metadata, self.bind
         canary = self.Canary(metadata, bind)
-            
+
         event.listen(metadata, 'before_create', canary.before_create)
         event.listen(metadata, 'after_create', canary.after_create)
 
@@ -259,7 +259,7 @@ class DDLExecutionTest(TestBase):
         assert 'xyzzy' in strings
         assert 'fnord' in strings
 
-        
+
     def test_metadata(self):
         metadata, engine = self.metadata, self.engine
 
@@ -320,13 +320,13 @@ class DDLExecutionTest(TestBase):
             'after_create',
             AddConstraint(constraint).execute_if(dialect='postgresql'),
         )
-        
+
         event.listen(
             users,
             'before_drop',
             DropConstraint(constraint).execute_if(dialect='postgresql'),
         )
-        
+
         metadata.create_all(bind=nonpg_mock)
         strings = ' '.join(str(x) for x in nonpg_mock.mock)
         assert 'my_test_constraint' not in strings
@@ -339,7 +339,7 @@ class DDLExecutionTest(TestBase):
         metadata.drop_all(bind=pg_mock)
         strings = ' '.join(str(x) for x in pg_mock.mock)
         assert 'my_test_constraint' in strings
-    
+
     @testing.uses_deprecated(r'See DDLEvents')
     def test_conditional_constraint_deprecated(self):
         metadata, users, engine = self.metadata, self.users, self.engine
@@ -406,27 +406,27 @@ class DDLExecutionTest(TestBase):
     @testing.fails_on('postgresql+pg8000', 'pg8000 requires explicit types')
     def test_platform_escape(self):
         """test the escaping of % characters in the DDL construct."""
-        
+
         default_from = testing.db.dialect.statement_compiler(
                             testing.db.dialect, None).default_from()
-        
+
         eq_(
             testing.db.execute(
                 text("select 'foo%something'" + default_from)
             ).scalar(),
             'foo%something'
         )
-    
+
         eq_(
             testing.db.execute(
                 DDL("select 'foo%%something'" + default_from)
             ).scalar(),
             'foo%something'
         )
-    
 
-        
-        
+
+
+
 class DDLTest(TestBase, AssertsCompiledSQL):
     def mock_engine(self):
         executor = lambda *a, **kw: None
index 90d2bc578b3a5b84803cde006010c72bbb4aedca..9379e207f6e2b4b9b79f9f1bcafd44eb7e7d3917 100644 (file)
@@ -29,7 +29,7 @@ class ExecuteTest(TestBase):
     @engines.close_first
     def teardown(self):
         testing.db.connect().execute(users.delete())
-        
+
     @classmethod
     def teardown_class(cls):
         metadata.drop_all()
@@ -152,7 +152,7 @@ class ExecuteTest(TestBase):
         eng.update_execution_options(foo='hoho')
         conn = eng.contextual_connect()
         eq_(conn._execution_options['foo'], 'hoho')
-        
+
 
 class CompiledCacheTest(TestBase):
     @classmethod
@@ -169,23 +169,23 @@ class CompiledCacheTest(TestBase):
     @engines.close_first
     def teardown(self):
         testing.db.connect().execute(users.delete())
-        
+
     @classmethod
     def teardown_class(cls):
         metadata.drop_all()
-    
+
     def test_cache(self):
         conn = testing.db.connect()
         cache = {}
         cached_conn = conn.execution_options(compiled_cache=cache)
-        
+
         ins = users.insert()
         cached_conn.execute(ins, {'user_name':'u1'})
         cached_conn.execute(ins, {'user_name':'u2'})
         cached_conn.execute(ins, {'user_name':'u3'})
         assert len(cache) == 1
         eq_(conn.execute("select count(*) from users").scalar(), 3)
-    
+
 class LoggingNameTest(TestBase):
     def _assert_names_in_execute(self, eng, eng_name, pool_name):
         eng.execute(select([1]))
@@ -203,7 +203,7 @@ class LoggingNameTest(TestBase):
                 'sqlalchemy.engine.base.Engine',
                 'sqlalchemy.pool.%s' % eng.pool.__class__.__name__
             )
-    
+
     def _named_engine(self, **kw):
         options = {
             'logging_name':'myenginename',
@@ -229,24 +229,24 @@ class LoggingNameTest(TestBase):
             logging.getLogger('sqlalchemy.pool')
         ]:
             log.removeHandler(self.buf)
-        
+
     def test_named_logger_names(self):
         eng = self._named_engine()
         eq_(eng.logging_name, "myenginename")
         eq_(eng.pool.logging_name, "mypoolname")
-        
+
     def test_named_logger_names_after_dispose(self):
         eng = self._named_engine()
         eng.execute(select([1]))
         eng.dispose()
         eq_(eng.logging_name, "myenginename")
         eq_(eng.pool.logging_name, "mypoolname")
-    
+
     def test_unnamed_logger_names(self):
         eng = self._unnamed_engine()
         eq_(eng.logging_name, None)
         eq_(eng.pool.logging_name, None)
-    
+
     def test_named_logger_execute(self):
         eng = self._named_engine()
         self._assert_names_in_execute(eng, "myenginename", "mypoolname")
@@ -270,27 +270,27 @@ class LoggingNameTest(TestBase):
         self._assert_no_name_in_execute(eng)
 
 class EchoTest(TestBase):
-    
+
     def setup(self):
         self.level = logging.getLogger('sqlalchemy.engine').level
         logging.getLogger('sqlalchemy.engine').setLevel(logging.WARN)
         self.buf = logging.handlers.BufferingHandler(100)
         logging.getLogger('sqlalchemy.engine').addHandler(self.buf)
-    
+
     def teardown(self):
         logging.getLogger('sqlalchemy.engine').removeHandler(self.buf)
         logging.getLogger('sqlalchemy.engine').setLevel(self.level)
-    
+
     def testing_engine(self):
         e = engines.testing_engine()
-        
+
         # do an initial execute to clear out 'first connect'
         # messages
         e.execute(select([10]))
         self.buf.flush()
-        
+
         return e
-        
+
     def test_levels(self):
         e1 = engines.testing_engine()
 
@@ -310,40 +310,40 @@ class EchoTest(TestBase):
         eq_(e1._should_log_debug(), True)
         eq_(e1.logger.isEnabledFor(logging.DEBUG), True)
         eq_(e1.logger.getEffectiveLevel(), logging.DEBUG)
-        
+
         e1.echo = False
         eq_(e1._should_log_info(), False)
         eq_(e1._should_log_debug(), False)
         eq_(e1.logger.isEnabledFor(logging.INFO), False)
         eq_(e1.logger.getEffectiveLevel(), logging.WARN)
-        
+
     def test_echo_flag_independence(self):
         """test the echo flag's independence to a specific engine."""
 
         e1 = self.testing_engine()
         e2 = self.testing_engine()
-        
+
         e1.echo = True
         e1.execute(select([1]))
         e2.execute(select([2]))
-        
+
         e1.echo = False
         e1.execute(select([3]))
         e2.execute(select([4]))
-        
+
         e2.echo = True
         e1.execute(select([5]))
         e2.execute(select([6]))
-        
+
         assert self.buf.buffer[0].getMessage().startswith("SELECT 1")
         assert self.buf.buffer[2].getMessage().startswith("SELECT 6")
         assert len(self.buf.buffer) == 4
-    
+
 class ResultProxyTest(TestBase):
     def test_nontuple_row(self):
         """ensure the C version of BaseRowProxy handles 
         duck-type-dependent rows."""
-        
+
         from sqlalchemy.engine import RowProxy
 
         class MyList(object):
@@ -373,7 +373,7 @@ class ResultProxyTest(TestBase):
 
         engine = engines.testing_engine()
         metadata.bind = engine
-        
+
         t = Table('t1', metadata,
             Column('data', String(10))
         )
@@ -383,7 +383,7 @@ class ResultProxyTest(TestBase):
             @property
             def rowcount(self):
                 assert False
-        
+
         execution_ctx_cls = engine.dialect.execution_ctx_cls
         engine.dialect.execution_ctx_cls = type("FakeCtx", 
                                             (BreakRowcountMixin, 
@@ -409,13 +409,13 @@ class ResultProxyTest(TestBase):
         row = RowProxy(object(), ['value'], [None], {'key'
                          : (None, 0), 0: (None, 0)})
         assert isinstance(row, collections.Sequence)
-    
+
     @testing.requires.cextensions
     def test_row_c_sequence_check(self):
         import csv
         import collections
         from StringIO import StringIO
-        
+
         metadata = MetaData()
         metadata.bind = 'sqlite://'
         users = Table('users', metadata,
@@ -470,7 +470,7 @@ class EngineEventsTest(TestBase):
             ]:
             event.listen(engine, 'before_execute', execute)
             event.listen(engine, 'before_cursor_execute', cursor_execute)
-            
+
             m = MetaData(engine)
             t1 = Table('t1', m, 
                 Column('c1', Integer, primary_key=True), 
@@ -523,10 +523,10 @@ class EngineEventsTest(TestBase):
         canary = []
         def execute(conn, *args, **kw):
             canary.append('execute')
-            
+
         def cursor_execute(conn, *args, **kw):
             canary.append('cursor_execute')
-            
+
         engine = engines.testing_engine()
         event.listen(engine, 'before_execute', execute)
         event.listen(engine, 'before_cursor_execute', cursor_execute)
@@ -548,42 +548,42 @@ class EngineEventsTest(TestBase):
         def execute(conn, clauseelement, multiparams, params):
             canary.append('execute')
             return clauseelement, multiparams, params
-            
+
         def cursor_execute(conn, cursor, statement, 
                         parameters, context, executemany):
             canary.append('cursor_execute')
             return statement, parameters
-            
+
         engine = engines.testing_engine()
-        
+
         assert_raises(
             tsa.exc.ArgumentError,
             event.listen, engine, "begin", tracker("begin"), retval=True
         )
-        
+
         event.listen(engine, "before_execute", execute, retval=True)
         event.listen(engine, "before_cursor_execute", cursor_execute, retval=True)
         engine.execute(select([1]))
         eq_(
             canary, ['execute', 'cursor_execute']
         )
-        
-        
-        
+
+
+
     def test_transactional(self):
         canary = []
         def tracker(name):
             def go(conn, *args, **kw):
                 canary.append(name)
             return go
-            
+
         engine = engines.testing_engine()
         event.listen(engine, 'before_execute', tracker('execute'))
         event.listen(engine, 'before_cursor_execute', tracker('cursor_execute'))
         event.listen(engine, 'begin', tracker('begin'))
         event.listen(engine, 'commit', tracker('commit'))
         event.listen(engine, 'rollback', tracker('rollback'))
-        
+
         conn = engine.connect()
         trans = conn.begin()
         conn.execute(select([1]))
@@ -605,7 +605,7 @@ class EngineEventsTest(TestBase):
             def go(*args, **kw):
                 canary.append(name)
             return go
-            
+
         engine = engines.testing_engine()
         for name in ['begin', 'savepoint', 
                     'rollback_savepoint', 'release_savepoint',
@@ -634,21 +634,21 @@ class EngineEventsTest(TestBase):
                     'rollback', 'begin_twophase', 
                        'prepare_twophase', 'commit_twophase']
         )
-    
-        
+
+
 class ProxyConnectionTest(TestBase):
     """These are the same tests as EngineEventsTest, except using
     the deprecated ConnectionProxy interface.
-    
+
     """
-    
+
     @testing.uses_deprecated(r'.*Use event.listen')
     @testing.fails_on('firebird', 'Data type unknown')
     def test_proxy(self):
-        
+
         stmts = []
         cursor_stmts = []
-        
+
         class MyProxy(ConnectionProxy):
             def execute(
                 self,
@@ -672,7 +672,7 @@ class ProxyConnectionTest(TestBase):
                 ):
                 cursor_stmts.append((str(statement), parameters, None))
                 return execute(cursor, statement, parameters, context)
-        
+
         def assert_stmts(expected, received):
             for stmt, params, posn in expected:
                 if not received:
@@ -739,7 +739,7 @@ class ProxyConnectionTest(TestBase):
                                       # be incorrect
             assert_stmts(compiled, stmts)
             assert_stmts(cursor, cursor_stmts)
-    
+
     @testing.uses_deprecated(r'.*Use event.listen')
     def test_options(self):
         canary = []
@@ -758,8 +758,8 @@ class ProxyConnectionTest(TestBase):
         c3 = c2.execution_options(bar='bat')
         eq_(c3._execution_options, {'foo':'bar', 'bar':'bat'})
         eq_(canary, ['execute', 'cursor_execute'])
-        
-        
+
+
     @testing.uses_deprecated(r'.*Use event.listen')
     def test_transactional(self):
         canary = []
@@ -779,12 +779,12 @@ class ProxyConnectionTest(TestBase):
         trans = conn.begin()
         conn.execute(select([1]))
         trans.commit()
-        
+
         eq_(canary, [
             'begin', 'execute', 'cursor_execute', 'rollback',
             'begin', 'execute', 'cursor_execute', 'commit',
             ])
-        
+
     @testing.uses_deprecated(r'.*Use event.listen')
     @testing.requires.savepoints
     @testing.requires.two_phase_transactions
@@ -800,7 +800,7 @@ class ProxyConnectionTest(TestBase):
 
         engine = engines.testing_engine(options={'proxy':TrackProxy()})
         conn = engine.connect()
-        
+
         trans = conn.begin()
         trans2 = conn.begin_nested()
         conn.execute(select([1]))
@@ -809,7 +809,7 @@ class ProxyConnectionTest(TestBase):
         conn.execute(select([1]))
         trans2.commit()
         trans.rollback()
-        
+
         trans = conn.begin_twophase()
         conn.execute(select([1]))
         trans.prepare()
index 7000549e76661925ce30ba1b1a200b300bc20fb2..ee9af60bf93a88b0da43903e6d6abfd3b71045de 100644 (file)
@@ -56,7 +56,7 @@ class DialectImportTest(TestBase):
             exec ('from sqlalchemy.dialects import %s\ndialect = '
                   '%s.dialect()' % (name, name), globals())
             eq_(dialect.name, name)
-    
+
 class CreateEngineTest(TestBase):
     """test that create_engine arguments of different types get
     propagated properly"""
index e9679fee4b78249b9699e1f121da7ac8d880c9f7..4e818894fafb434f3aa4ce369d67d83490cda25d 100644 (file)
@@ -33,10 +33,10 @@ class MockCursor(object):
     def close(self):
         pass
 
-class PoolTestBase(TestBase):    
+class PoolTestBase(TestBase):
     def setup(self):
         pool.clear_managers()
-        
+
     @classmethod
     def teardown_class(cls):
        pool.clear_managers()
@@ -48,7 +48,7 @@ class PoolTestBase(TestBase):
     def _queuepool_dbapi_fixture(self, **kw):
         dbapi = MockDBAPI()
         return dbapi, pool.QueuePool(creator=lambda: dbapi.connect('foo.db'), **kw)
-     
+
 class PoolTest(PoolTestBase):
     def testmanager(self):
         manager = pool.manage(MockDBAPI(), use_threadlocal=True)
@@ -87,17 +87,17 @@ class PoolTest(PoolTestBase):
         expected = [(1, )]
         for row in cursor:
             eq_(row, expected.pop(0))
-    
+
     def test_no_connect_on_recreate(self):
         def creator():
             raise Exception("no creates allowed")
-        
+
         for cls in (pool.SingletonThreadPool, pool.StaticPool, 
                     pool.QueuePool, pool.NullPool, pool.AssertionPool):
             p = cls(creator=creator)
             p.dispose()
             p.recreate()
-        
+
             mock_dbapi = MockDBAPI()
             p = cls(creator=mock_dbapi.connect)
             conn = p.connect()
@@ -105,7 +105,7 @@ class PoolTest(PoolTestBase):
             mock_dbapi.throw_error = True
             p.dispose()
             p.recreate()
-            
+
     def testthreadlocal_del(self):
         self._do_testthreadlocal(useclose=False)
 
@@ -198,9 +198,9 @@ class PoolEventsTest(PoolTestBase):
         canary = []
         def first_connect(*arg, **kw):
             canary.append('first_connect')
-        
+
         event.listen(p, 'first_connect', first_connect)
-        
+
         return p, canary
 
     def _connect_event_fixture(self):
@@ -209,7 +209,7 @@ class PoolEventsTest(PoolTestBase):
         def connect(*arg, **kw):
             canary.append('connect')
         event.listen(p, 'connect', connect)
-        
+
         return p, canary
 
     def _checkout_event_fixture(self):
@@ -218,7 +218,7 @@ class PoolEventsTest(PoolTestBase):
         def checkout(*arg, **kw):
             canary.append('checkout')
         event.listen(p, 'checkout', checkout)
-        
+
         return p, canary
 
     def _checkin_event_fixture(self):
@@ -227,18 +227,18 @@ class PoolEventsTest(PoolTestBase):
         def checkin(*arg, **kw):
             canary.append('checkin')
         event.listen(p, 'checkin', checkin)
-        
+
         return p, canary
-        
+
     def test_first_connect_event(self):
         p, canary = self._first_connect_event_fixture()
-        
+
         c1 = p.connect()
         eq_(canary, ['first_connect'])
 
     def test_first_connect_event_fires_once(self):
         p, canary = self._first_connect_event_fixture()
-        
+
         c1 = p.connect()
         c2 = p.connect()
 
@@ -264,13 +264,13 @@ class PoolEventsTest(PoolTestBase):
 
     def test_connect_event(self):
         p, canary = self._connect_event_fixture()
-        
+
         c1 = p.connect()
         eq_(canary, ['connect'])
 
     def test_connect_event_fires_subsequent(self):
         p, canary = self._connect_event_fixture()
-        
+
         c1 = p.connect()
         c2 = p.connect()
 
@@ -280,7 +280,7 @@ class PoolEventsTest(PoolTestBase):
         p, canary = self._connect_event_fixture()
 
         p2 = p.recreate()
-        
+
         c1 = p.connect()
         c2 = p2.connect()
 
@@ -294,40 +294,40 @@ class PoolEventsTest(PoolTestBase):
         c2 = p2.connect()
 
         eq_(canary, ['connect', 'connect'])
-    
+
     def test_checkout_event(self):
         p, canary = self._checkout_event_fixture()
-        
+
         c1 = p.connect()
         eq_(canary, ['checkout'])
 
     def test_checkout_event_fires_subsequent(self):
         p, canary = self._checkout_event_fixture()
-        
+
         c1 = p.connect()
         c2 = p.connect()
         eq_(canary, ['checkout', 'checkout'])
 
     def test_checkout_event_on_subsequently_recreated(self):
         p, canary = self._checkout_event_fixture()
-        
+
         c1 = p.connect()
         p2 = p.recreate()
         c2 = p2.connect()
-        
+
         eq_(canary, ['checkout', 'checkout'])
-        
+
     def test_checkin_event(self):
         p, canary = self._checkin_event_fixture()
-        
+
         c1 = p.connect()
         eq_(canary, [])
         c1.close()
         eq_(canary, ['checkin'])
-    
+
     def test_checkin_event_gc(self):
         p, canary = self._checkin_event_fixture()
-        
+
         c1 = p.connect()
         eq_(canary, [])
         del c1
@@ -336,19 +336,19 @@ class PoolEventsTest(PoolTestBase):
 
     def test_checkin_event_on_subsequently_recreated(self):
         p, canary = self._checkin_event_fixture()
-        
+
         c1 = p.connect()
         p2 = p.recreate()
         c2 = p2.connect()
-        
+
         eq_(canary, [])
-        
+
         c1.close()
         eq_(canary, ['checkin'])
-        
+
         c2.close()
         eq_(canary, ['checkin', 'checkin'])
-        
+
     def test_listen_targets_scope(self):
         canary = []
         def listen_one(*args):
@@ -359,7 +359,7 @@ class PoolEventsTest(PoolTestBase):
             canary.append("listen_three")
         def listen_four(*args):
             canary.append("listen_four")
-            
+
         engine = create_engine(testing.db.url)
         event.listen(pool.Pool, 'connect', listen_one)
         event.listen(engine.pool, 'connect', listen_two)
@@ -370,10 +370,10 @@ class PoolEventsTest(PoolTestBase):
         eq_(
             canary, ["listen_one","listen_four", "listen_two","listen_three"]
         )
-    
+
     def test_listen_targets_per_subclass(self):
         """test that listen() called on a subclass remains specific to that subclass."""
-        
+
         canary = []
         def listen_one(*args):
             canary.append("listen_one")
@@ -381,14 +381,14 @@ class PoolEventsTest(PoolTestBase):
             canary.append("listen_two")
         def listen_three(*args):
             canary.append("listen_three")
-        
+
         event.listen(pool.Pool, 'connect', listen_one)
         event.listen(pool.QueuePool, 'connect', listen_two)
         event.listen(pool.SingletonThreadPool, 'connect', listen_three)
-        
+
         p1 = pool.QueuePool(creator=MockDBAPI().connect)
         p2 = pool.SingletonThreadPool(creator=MockDBAPI().connect)
-        
+
         assert listen_one in p1.dispatch.connect
         assert listen_two in p1.dispatch.connect
         assert listen_three not in p1.dispatch.connect
@@ -400,12 +400,12 @@ class PoolEventsTest(PoolTestBase):
         eq_(canary, ["listen_one", "listen_two"])
         p2.connect()
         eq_(canary, ["listen_one", "listen_two", "listen_one", "listen_three"])
-        
+
     def teardown(self):
         # TODO: need to get remove() functionality
         # going
         pool.Pool.dispatch._clear()
-        
+
 class DeprecatedPoolListenerTest(PoolTestBase):
     @testing.uses_deprecated(r".*Use event.listen")
     def test_listeners(self):
@@ -581,7 +581,7 @@ class DeprecatedPoolListenerTest(PoolTestBase):
         snoop.assert_total(1, 1, 2, 1)
         c.close()
         snoop.assert_total(1, 1, 2, 2)
-    
+
     @testing.uses_deprecated(r".*Use event.listen")
     def test_listeners_callables(self):
         def connect(dbapi_con, con_record):
@@ -694,7 +694,7 @@ class QueuePoolTest(PoolTestBase):
         c1.close()
         lazy_gc()
         assert not pool._refs
-       
+
     def test_timeout(self):
         p = self._queuepool_fixture(pool_size=3,
                            max_overflow=0, 
@@ -732,7 +732,7 @@ class QueuePoolTest(PoolTestBase):
                     timeouts.append(time.time() - now)
                     continue
                 time.sleep(4)
-                c1.close()  
+                c1.close()
 
         threads = []
         for i in xrange(10):
@@ -751,7 +751,7 @@ class QueuePoolTest(PoolTestBase):
 
     def _test_overflow(self, thread_count, max_overflow):
         gc_collect()
-        
+
         dbapi = MockDBAPI()
         def creator():
             time.sleep(.05)
@@ -780,7 +780,7 @@ class QueuePoolTest(PoolTestBase):
             th.join()
  
         self.assert_(max(peaks) <= max_overflow)
-        
+
         lazy_gc()
         assert not pool._refs
  
@@ -824,7 +824,7 @@ class QueuePoolTest(PoolTestBase):
         counter, you can fool the counter into giving you a
         ConnectionFairy with an ambiguous counter.  i.e. its not true
         reference counting."""
-        
+
         p = self._queuepool_fixture(pool_size=3,
                            max_overflow=-1, use_threadlocal=True)
         c1 = p.connect()
@@ -918,7 +918,7 @@ class SingletonThreadPoolTest(PoolTestBase):
     def test_cleanup(self):
         """test that the pool's connections are OK after cleanup() has
         been called."""
-        
+
         dbapi = MockDBAPI()
         p = pool.SingletonThreadPool(creator=dbapi.connect,
                 pool_size=3)
index e2898580165787295cb881b3da5245806f302ddc..ed68fa475fdc896ec4a96e0c016d0ef064feaa0b 100644 (file)
@@ -56,7 +56,7 @@ class MockReconnectTest(TestBase):
         db = tsa.create_engine(
                     'postgresql://foo:bar@localhost/test', 
                     module=dbapi, _initialize=False)
-        
+
         # monkeypatch disconnect checker
         db.dialect.is_disconnect = lambda e: isinstance(e, MockDisconnect)
 
@@ -184,11 +184,11 @@ class CursorErrTest(TestBase):
 
     def setup(self):
         global db, dbapi
-        
+
         class MDBAPI(MockDBAPI):
             def connect(self, *args, **kwargs):
                 return MConn(self)
-            
+
         class MConn(MockConnection):
             def cursor(self):
                 return MCursor(self)
@@ -202,16 +202,16 @@ class CursorErrTest(TestBase):
         db = tsa.create_engine(
                     'postgresql://foo:bar@localhost/test', 
                     module=dbapi, _initialize=False)
-    
+
     def test_cursor_explode(self):
         conn = db.connect()
         result = conn.execute("select foo")
         result.close()
         conn.close()
-    
+
     def teardown(self):
         db.dispose()
-        
+
 engine = None
 class RealReconnectTest(TestBase):
     def setup(self):
@@ -263,14 +263,14 @@ class RealReconnectTest(TestBase):
         conn = engine.connect()
         conn.invalidate()
         conn.invalidate()
-    
+
     def test_explode_in_initializer(self):
         engine = engines.testing_engine()
         def broken_initialize(connection):
             connection.execute("select fake_stuff from _fake_table")
-            
+
         engine.dialect.initialize = broken_initialize
-        
+
         # raises a DBAPIError, not an AttributeError
         assert_raises(exc.DBAPIError, engine.connect)
 
@@ -279,15 +279,15 @@ class RealReconnectTest(TestBase):
         engine.dispose()
 
         p1 = engine.pool
-        
+
         def is_disconnect(e):
             return True
-            
+
         engine.dialect.is_disconnect = is_disconnect
 
         # invalidate() also doesn't screw up
         assert_raises(exc.DBAPIError, engine.connect)
-        
+
         # pool was recreated
         assert engine.pool is not p1
 
@@ -310,7 +310,7 @@ class RealReconnectTest(TestBase):
         assert conn.invalidated
         eq_(conn.execute(select([1])).scalar(), 1)
         assert not conn.invalidated
-        
+
     @testing.fails_on('+informixdb',
                       "Wrong error thrown, fix in informixdb?")
     def test_close(self):
@@ -384,7 +384,7 @@ class RecycleTest(TestBase):
             conn = engine.contextual_connect()
             eq_(conn.execute(select([1])).scalar(), 1)
             conn.close()
-    
+
 meta, table, engine = None, None, None
 class InvalidateDuringResultTest(TestBase):
     def setup(self):
index 5fd18dc81ffc3452291cd2225f21037f5611f6f8..8e7049b8f90bbe8c4083797484e8a4aef56e78f2 100644 (file)
@@ -63,7 +63,7 @@ class ReflectionTest(TestBase, ComparesTables):
             self.assert_tables_equal(addresses, reflected_addresses)
         finally:
             meta.drop_all()
-    
+
     def test_two_foreign_keys(self):
         meta = MetaData(testing.db)
         t1 = Table(
@@ -88,12 +88,12 @@ class ReflectionTest(TestBase, ComparesTables):
             assert t1r.c.t3id.references(t3r.c.id)
         finally:
             meta.drop_all()
-    
+
     def test_nonexistent(self):
         meta = MetaData(testing.db)
         assert_raises(sa.exc.NoSuchTableError, Table, 'nonexistent',
                       meta, autoload=True)
-        
+
     def test_include_columns(self):
         meta = MetaData(testing.db)
         foo = Table('foo', meta, *[Column(n, sa.String(30))
@@ -126,7 +126,7 @@ class ReflectionTest(TestBase, ComparesTables):
     @testing.emits_warning(r".*omitted columns")
     def test_include_columns_indexes(self):
         m = MetaData(testing.db)
-        
+
         t1 = Table('t1', m, Column('a', sa.Integer), Column('b', sa.Integer))
         sa.Index('foobar', t1.c.a, t1.c.b)
         sa.Index('bat', t1.c.a)
@@ -148,13 +148,13 @@ class ReflectionTest(TestBase, ComparesTables):
 
     def test_autoincrement_col(self):
         """test that 'autoincrement' is reflected according to sqla's policy.
-        
+
         Don't mark this test as unsupported for any backend !
-        
+
         (technically it fails with MySQL InnoDB since "id" comes before "id2")
-        
+
         """
-        
+
         meta = MetaData(testing.db)
         t1 = Table('test', meta,
             Column('id', sa.Integer, primary_key=True),
@@ -171,13 +171,13 @@ class ReflectionTest(TestBase, ComparesTables):
             m2 = MetaData(testing.db)
             t1a = Table('test', m2, autoload=True)
             assert t1a._autoincrement_column is t1a.c.id
-            
+
             t2a = Table('test2', m2, autoload=True)
             assert t2a._autoincrement_column is t2a.c.id2
-            
+
         finally:
             meta.drop_all()
-            
+
     def test_unknown_types(self):
         meta = MetaData(testing.db)
         t = Table("test", meta,
@@ -307,7 +307,7 @@ class ReflectionTest(TestBase, ComparesTables):
             u4 = Table('users', meta4, 
                     Column('id', sa.Integer, key='u_id', primary_key=True),
                     autoload=True)
-                    
+
             a4 = Table(
                 'addresses',
                 meta4,
@@ -326,7 +326,7 @@ class ReflectionTest(TestBase, ComparesTables):
             assert len(a4.constraints) == 2
         finally:
             meta.drop_all()
-    
+
     @testing.provide_metadata
     def test_override_composite_fk(self):
         """Test double-remove of composite foreign key, when replaced."""
@@ -356,18 +356,18 @@ class ReflectionTest(TestBase, ComparesTables):
             autoload=True,
             autoload_with=testing.db
         )
-        
+
         assert b1.c.x is c1
         assert b1.c.y is c2
         assert f1 in b1.constraints
         assert len(b1.constraints) == 2
-        
-        
-        
+
+
+
     def test_override_keys(self):
         """test that columns can be overridden with a 'key', 
         and that ForeignKey targeting during reflection still works."""
-        
+
 
         meta = MetaData(testing.db)
         a1 = Table('a', meta,
@@ -390,12 +390,12 @@ class ReflectionTest(TestBase, ComparesTables):
             assert b2.c.y.references(a2.c.x1)
         finally:
             meta.drop_all()
-    
+
     def test_nonreflected_fk_raises(self):
         """test that a NoReferencedColumnError is raised when reflecting
         a table with an FK to another table which has not included the target
         column in its reflection.
-        
+
         """
         meta = MetaData(testing.db)
         a1 = Table('a', meta,
@@ -412,12 +412,12 @@ class ReflectionTest(TestBase, ComparesTables):
             m2 = MetaData(testing.db)
             a2 = Table('a', m2, include_columns=['z'], autoload=True)
             b2 = Table('b', m2, autoload=True)
-            
+
             assert_raises(sa.exc.NoReferencedColumnError, a2.join, b2)
         finally:
             meta.drop_all()
-        
-        
+
+
     @testing.exclude('mysql', '<', (4, 1, 1), 'innodb funkiness')
     def test_override_existing_fk(self):
         """test that you can override columns and specify new foreign
@@ -442,7 +442,7 @@ class ReflectionTest(TestBase, ComparesTables):
                     autoload=True)
             u2 = Table('users', meta2, autoload=True)
             s = sa.select([a2])
-            
+
             assert s.c.user_id is not None
             assert len(a2.foreign_keys) == 1
             assert len(a2.c.user_id.foreign_keys) == 1
@@ -453,7 +453,7 @@ class ReflectionTest(TestBase, ComparesTables):
             assert list(a2.c.user_id.foreign_keys)[0].parent \
                 is a2.c.user_id
             assert u2.join(a2).onclause.compare(u2.c.id == a2.c.user_id)
-            
+
             meta2 = MetaData(testing.db)
             u2 = Table('users', meta2, Column('id', sa.Integer,
                        primary_key=True), autoload=True)
@@ -461,7 +461,7 @@ class ReflectionTest(TestBase, ComparesTables):
                        primary_key=True), Column('user_id', sa.Integer,
                        sa.ForeignKey('users.id')), autoload=True)
             s = sa.select([a2])
-            
+
             assert s.c.user_id is not None
             assert len(a2.foreign_keys) == 1
             assert len(a2.c.user_id.foreign_keys) == 1
@@ -472,7 +472,7 @@ class ReflectionTest(TestBase, ComparesTables):
             assert list(a2.c.user_id.foreign_keys)[0].parent \
                 is a2.c.user_id
             assert u2.join(a2).onclause.compare(u2.c.id == a2.c.user_id)
-            
+
         finally:
             meta.drop_all()
 
@@ -545,7 +545,7 @@ class ReflectionTest(TestBase, ComparesTables):
             Column('pkg_id', sa.Integer, sa.ForeignKey('pkgs.pkg_id')),
             Column('slot', sa.String(128)),
             )
-            
+
         assert_raises_message(sa.exc.InvalidRequestError,
                             "Foreign key assocated with column 'slots.pkg_id' "
                             "could not find table 'pkgs' with which to generate "
@@ -642,14 +642,14 @@ class ReflectionTest(TestBase, ComparesTables):
         else:
             check_col = 'true'
         quoter = meta.bind.dialect.identifier_preparer.quote_identifier
-        
+
         table_b = Table('false', meta, 
                     Column('create', sa.Integer, primary_key=True), 
                     Column('true', sa.Integer,sa.ForeignKey('select.not')),
                     sa.CheckConstraint('%s <> 1'
                         % quoter(check_col), name='limit')
                     )
-                    
+
         table_c = Table('is', meta, 
                 Column('or', sa.Integer, nullable=False, primary_key=True), 
                 Column('join', sa.Integer, nullable=False, primary_key=True),
@@ -770,17 +770,17 @@ class ReflectionTest(TestBase, ComparesTables):
             m2 = MetaData(testing.db)
             users_v = Table("users_v", m2, autoload=True)
             addresses_v = Table("email_addresses_v", m2, autoload=True)
-        
+
             for c1, c2 in zip(users.c, users_v.c):
                 eq_(c1.name, c2.name)
                 self.assert_types_base(c1, c2)
-            
+
             for c1, c2 in zip(addresses.c, addresses_v.c):
                 eq_(c1.name, c2.name)
                 self.assert_types_base(c1, c2)
         finally:
-            dropViews(metadata.bind)    
-    
+            dropViews(metadata.bind)
+
     @testing.provide_metadata
     def test_reflect_all_with_views(self):
         users, addresses = createTables(metadata, None)
@@ -788,13 +788,13 @@ class ReflectionTest(TestBase, ComparesTables):
             metadata.create_all()
             createViews(metadata.bind, None)
             m2 = MetaData(testing.db)
-            
+
             m2.reflect(views=False)
             eq_(
                 set(m2.tables), 
                 set([u'users', u'email_addresses'])
             )
-            
+
             m2 = MetaData(testing.db)
             m2.reflect(views=True)
             eq_(
@@ -804,7 +804,7 @@ class ReflectionTest(TestBase, ComparesTables):
             )
         finally:
             dropViews(metadata.bind)
-            
+
 class CreateDropTest(TestBase):
 
     @classmethod
@@ -816,7 +816,7 @@ class CreateDropTest(TestBase):
                       sa.Sequence('user_id_seq', optional=True),
                       primary_key=True), 
                     Column('user_name',sa.String(40)))
-                      
+
         addresses = Table('email_addresses', metadata,
                       Column('address_id', sa.Integer,
                           sa.Sequence('address_id_seq', optional=True),
@@ -846,10 +846,10 @@ class CreateDropTest(TestBase):
         table_names = [t.name for t in tables]
         ua = [n for n in table_names if n in ('users', 'email_addresses')]
         oi = [n for n in table_names if n in ('orders', 'items')]
-        
+
         eq_(ua, ['users', 'email_addresses'])
         eq_(oi, ['orders', 'items'])
-        
+
 
     def testcheckfirst(self):
         try:
@@ -993,7 +993,7 @@ class SchemaTest(TestBase):
             schema = engine.dialect.default_schema_name
 
         assert bool(schema)
-        
+
         metadata = MetaData(engine)
         table1 = Table('table1', metadata,
                        Column('col1', sa.Integer, primary_key=True),
@@ -1057,7 +1057,7 @@ class HasSequenceTest(TestBase):
             schema=test_schema), False)
         eq_(testing.db.dialect.has_sequence(testing.db, 'user_id_seq'),
             False)
-        
+
 # Tests related to engine.reflection
 
 
@@ -1158,7 +1158,7 @@ class ComponentReflectionTest(TestBase):
     @testing.requires.schemas
     def test_get_schema_names(self):
         insp = Inspector(testing.db)
-        
+
         self.assert_('test_schema' in insp.get_schema_names())
 
     def test_dialect_initialize(self):
@@ -1166,11 +1166,11 @@ class ComponentReflectionTest(TestBase):
         assert not hasattr(engine.dialect, 'default_schema_name')
         insp = Inspector(engine)
         assert hasattr(engine.dialect, 'default_schema_name')
-        
+
     def test_get_default_schema_name(self):
         insp = Inspector(testing.db)
         eq_(insp.default_schema_name, testing.db.dialect.default_schema_name)
-        
+
     def _test_get_table_names(self, schema=None, table_type='table',
                               order_by=None):
         meta = MetaData(testing.db)
@@ -1287,15 +1287,15 @@ class ComponentReflectionTest(TestBase):
             eq_(users_pkeys,  ['user_id'])
             addr_cons = insp.get_pk_constraint(addresses.name,
                                                 schema=schema)
-                                                
+
             addr_pkeys = addr_cons['constrained_columns']
             eq_(addr_pkeys,  ['address_id'])
-            
+
             @testing.requires.reflects_pk_names
             def go():
                 eq_(addr_cons['name'], 'email_ad_pk')
             go()
-            
+
         finally:
             addresses.drop()
             users.drop()
index 01a561d7b8544fde6b48fd29496fa4ccc968b975..e3176a45a1f84bbb500222b98aaa401352d5dde1 100644 (file)
@@ -77,7 +77,7 @@ class TransactionTest(TestBase):
         result = connection.execute("select * from query_users")
         assert len(result.fetchall()) == 0
         connection.close()
-    
+
     def test_transaction_container(self):
 
         def go(conn, table, data):
@@ -93,7 +93,7 @@ class TransactionTest(TestBase):
                       {'user_id': 1, 'user_name': 'user3'}])
         eq_(testing.db.execute(users.select()).fetchall(), [(1, 'user1'
             )])
-        
+
     def test_nested_rollback(self):
         connection = testing.db.connect()
         try:
@@ -138,7 +138,7 @@ class TransactionTest(TestBase):
             eq_(connection.scalar("select count(*) from query_users"), 0)
         finally:
             connection.close()
-        
+
     def test_nesting(self):
         connection = testing.db.connect()
         transaction = connection.begin()
@@ -295,7 +295,7 @@ class TransactionTest(TestBase):
             order_by(users.c.user_id)).fetchall(),
             [(1, ), (2, ), (5, )])
         connection.close()
-            
+
     @testing.requires.two_phase_transactions
     @testing.crashes('mysql+oursql',
                      'Times out in full test runs only, causing '
@@ -350,7 +350,7 @@ class TransactionTest(TestBase):
                 order_by(users.c.user_id))
         eq_(result.fetchall(), [('user1', ), ('user4', )])
         conn.close()
-            
+
 class AutoRollbackTest(TestBase):
 
     @classmethod
@@ -386,7 +386,7 @@ class AutoRollbackTest(TestBase):
 class ExplicitAutoCommitTest(TestBase):
 
     """test the 'autocommit' flag on select() and text() objects.
-    
+
     Requires PostgreSQL so that we may define a custom function which
     modifies the database. """
 
@@ -541,13 +541,13 @@ class TLTransactionTest(TestBase):
         # ensure tests start with engine closed
 
         tlengine.close()
-    
+
     def test_rollback_no_trans(self):
         tlengine = create_engine(testing.db.url, strategy="threadlocal")
 
         # shouldn't fail
         tlengine.rollback()
-        
+
         tlengine.begin()
         tlengine.rollback()
 
@@ -577,7 +577,7 @@ class TLTransactionTest(TestBase):
 
         # shouldn't fail
         tlengine.prepare()
-        
+
     def test_connection_close(self):
         """test that when connections are closed for real, transactions
         are rolled back and disposed."""
@@ -993,11 +993,11 @@ class ForUpdateTest(TestBase):
     @testing.requires.independent_connections
     def test_queued_update(self):
         """Test SELECT FOR UPDATE with concurrent modifications.
-        
+
         Runs concurrent modifications on a single row in the users
         table, with each mutator trying to increment a value stored in
         user_name.
-        
+
         """
 
         db = testing.db
index fb2f60ff1fff0a00900a6ef1b6083f039cf202d4..c319863c690d7b0ecfba461af91064ce555133f4 100644 (file)
@@ -634,7 +634,7 @@ class ProxyFactoryTest(ListTest):
                                       ForeignKey('Parent.id')),
                                Column('foo', String(128)),
                                Column('name', String(128)))
-        
+
         class CustomProxy(_AssociationList):
             def __init__(
                 self,
@@ -652,7 +652,7 @@ class ProxyFactoryTest(ListTest):
                     setter,
                     parent,
                     )
-        
+
         class Parent(object):
             children = association_proxy('_children', 'name', 
                         proxy_factory=CustomProxy, 
@@ -676,11 +676,11 @@ class ProxyFactoryTest(ListTest):
         self.metadata = metadata
         self.session = create_session()
         self.Parent, self.Child = Parent, Child
-    
+
     def test_sequence_ops(self):
         self._test_sequence_ops()
-    
-    
+
+
 class ScalarTest(TestBase):
     def test_scalar_proxy(self):
         metadata = MetaData(testing.db)
@@ -1002,7 +1002,7 @@ class ReconstitutionTest(TestBase):
 class PickleKeyFunc(object):
     def __init__(self, name):
         self.name = name
-    
+
     def __call__(self, obj):
         return getattr(obj, self.name)
 
@@ -1012,7 +1012,7 @@ class ComparatorTest(_base.MappedTest):
     run_deletes = None
     run_setup_mappers = 'once'
     run_setup_classes = 'once'
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('userkeywords', metadata, Column('keyword_id', Integer,
index 31b893b4834d755621a51112614027bcddfb62ae..d9bb778db8981debb17e511a4e08300688c38476 100644 (file)
@@ -28,11 +28,11 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
             select([MyThingy('x'), MyThingy('y')]).where(MyThingy() == 5),
             "SELECT >>x<<, >>y<< WHERE >>MYTHINGY!<< = :MYTHINGY!_1"
         )
-    
+
     def test_types(self):
         class MyType(TypeEngine):
             pass
-        
+
         @compiles(MyType, 'sqlite')
         def visit_type(type, compiler, **kw):
             return "SQLITE_FOO"
@@ -55,8 +55,8 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
             "POSTGRES_FOO",
             dialect=postgresql.dialect()
         )
-        
-        
+
+
     def test_stateful(self):
         class MyThingy(ColumnClause):
             def __init__(self):
@@ -101,20 +101,20 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
             "INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z "
             "FROM mytable WHERE mytable.x > :x_1)"
         )
-    
+
     def test_annotations(self):
         """test that annotated clause constructs use the 
         decorated class' compiler.
-        
+
         """
         t1 = table('t1', column('c1'), column('c2'))
-        
+
         dispatch = Select._compiler_dispatch
         try:
             @compiles(Select)
             def compile(element, compiler, **kw):
                 return "OVERRIDE"
-            
+
             s1 = select([t1])
             self.assert_compile(
                 s1, "OVERRIDE"
@@ -127,22 +127,22 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
             Select._compiler_dispatch = dispatch
             if hasattr(Select, '_compiler_dispatcher'):
                 del Select._compiler_dispatcher
-            
+
     def test_default_on_existing(self):
         """test that the existing compiler function remains
         as 'default' when overriding the compilation of an
         existing construct."""
-        
+
 
         t1 = table('t1', column('c1'), column('c2'))
-        
+
         dispatch = Select._compiler_dispatch
         try:
-            
+
             @compiles(Select, 'sqlite')
             def compile(element, compiler, **kw):
                 return "OVERRIDE"
-            
+
             s1 = select([t1])
             self.assert_compile(
                 s1, "SELECT t1.c1, t1.c2 FROM t1",
@@ -157,7 +157,7 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
             Select._compiler_dispatch = dispatch
             if hasattr(Select, '_compiler_dispatcher'):
                 del Select._compiler_dispatcher
-        
+
     def test_dialect_specific(self):
         class AddThingy(DDLElement):
             __visit_name__ = 'add_thingy'
@@ -211,18 +211,18 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
 
     def test_functions(self):
         from sqlalchemy.dialects.postgresql import base as postgresql
-        
+
         class MyUtcFunction(FunctionElement):
             pass
-            
+
         @compiles(MyUtcFunction)
         def visit_myfunc(element, compiler, **kw):
             return "utcnow()"
-            
+
         @compiles(MyUtcFunction, 'postgresql')
         def visit_myfunc(element, compiler, **kw):
             return "timezone('utc', current_timestamp)"
-            
+
         self.assert_compile(
             MyUtcFunction(),
             "utcnow()",
@@ -233,17 +233,17 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
             "timezone('utc', current_timestamp)",
             dialect=postgresql.dialect()
         )
-    
+
     def test_subclasses_one(self):
         class Base(FunctionElement):
             name = 'base'
-        
+
         class Sub1(Base):
             name = 'sub1'
 
         class Sub2(Base):
             name = 'sub2'
-        
+
         @compiles(Base)
         def visit_base(element, compiler, **kw):
             return element.name
@@ -257,11 +257,11 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
             'SELECT FOOsub1, sub2',
             use_default_dialect=True
         )
-    
+
     def test_subclasses_two(self):
         class Base(FunctionElement):
             name = 'base'
-        
+
         class Sub1(Base):
             name = 'sub1'
 
@@ -271,10 +271,10 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
 
         class Sub2(Base):
             name = 'sub2'
-        
+
         class SubSub1(Sub1):
             name = 'subsub1'
-            
+
         self.assert_compile(
             select([Sub1(), Sub2(), SubSub1()]),
             'SELECT sub1, sub2, subsub1',
@@ -290,4 +290,3 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
             'SELECT FOOsub1, sub2, FOOsubsub1',
             use_default_dialect=True
         )
-        
\ No newline at end of file
index 3daf8c74aed39261e8e7c76e452930d875d34511..d236cc3ab6b2724d7adac06163e467f60fed3dbf 100644 (file)
@@ -24,7 +24,7 @@ class DeclarativeTestBase(testing.TestBase, testing.AssertsExecutionResults):
     def teardown(self):
         clear_mappers()
         Base.metadata.drop_all()
-    
+
 class DeclarativeTest(DeclarativeTestBase):
     def test_basic(self):
         class User(Base, ComparableEntity):
@@ -49,7 +49,7 @@ class DeclarativeTest(DeclarativeTestBase):
         eq_(Address.__table__.c['id'].name, 'id')
         eq_(Address.__table__.c['_email'].name, 'email')
         eq_(Address.__table__.c['_user_id'].name, 'user_id')
-        
+
         u1 = User(name='u1', addresses=[
             Address(email='one'),
             Address(email='two'),
@@ -99,7 +99,7 @@ class DeclarativeTest(DeclarativeTestBase):
 
         assert class_mapper(Bar).get_property('some_data').columns[0] \
             is t.c.data
-    
+
     def test_difficult_class(self):
         """test no getattr() errors with a customized class"""
 
@@ -126,7 +126,7 @@ class DeclarativeTest(DeclarativeTestBase):
 
         decl.instrument_declarative(User,{},Base.metadata)
 
-        
+
     def test_undefer_column_name(self):
         # TODO: not sure if there was an explicit
         # test for this elsewhere
@@ -138,7 +138,7 @@ class DeclarativeTest(DeclarativeTestBase):
         eq_(str(foo), 'foo')
         eq_(foo.key, 'foo')
         eq_(foo.name, 'foo')
-        
+
     def test_recompile_on_othermapper(self):
         """declarative version of the same test in mappers.py"""
 
@@ -163,7 +163,7 @@ class DeclarativeTest(DeclarativeTestBase):
         u = User()
         assert User.addresses
         assert mapperlib._new_mappers is False
-    
+
     def test_string_dependency_resolution(self):
         from sqlalchemy.sql import desc
 
@@ -180,7 +180,7 @@ class DeclarativeTest(DeclarativeTestBase):
                     backref=backref('user',
                     primaryjoin='User.id==Address.user_id',
                     foreign_keys='[Address.user_id]'))
-        
+
         class Address(Base, ComparableEntity):
 
             __tablename__ = 'addresses'
@@ -249,7 +249,7 @@ class DeclarativeTest(DeclarativeTestBase):
         configure_mappers()
         eq_(str(User.addresses.prop.primaryjoin),
             'users.id = addresses.user_id')
-        
+
     def test_string_dependency_resolution_in_backref(self):
 
         class User(Base, ComparableEntity):
@@ -271,7 +271,7 @@ class DeclarativeTest(DeclarativeTestBase):
         configure_mappers()
         eq_(str(User.addresses.property.primaryjoin),
             str(Address.user.property.primaryjoin))
-        
+
     def test_string_dependency_resolution_tables(self):
 
         class User(Base, ComparableEntity):
@@ -301,12 +301,12 @@ class DeclarativeTest(DeclarativeTestBase):
 
     def test_string_dependency_resolution_schemas(self):
         Base = decl.declarative_base()
-        
+
         class User(Base):
 
             __tablename__ = 'users'
             __table_args__ = {'schema':'fooschema'}
-            
+
             id = Column(Integer, primary_key=True)
             name = Column(String(50))
             props = relationship('Prop', secondary='fooschema.user_to_prop',
@@ -327,7 +327,7 @@ class DeclarativeTest(DeclarativeTestBase):
                      Column('prop_id',Integer, ForeignKey('fooschema.props.id')),
                      schema='fooschema')
         configure_mappers()
-        
+
         assert class_mapper(User).get_property('props').secondary \
             is user_to_prop
 
@@ -370,7 +370,7 @@ class DeclarativeTest(DeclarativeTestBase):
         eq_(sess.query(User).filter(User.name == 'ed').one(),
             User(name='ed', addresses=[Address(email='abc'),
             Address(email='def'), Address(email='xyz')]))
-            
+
     def test_nice_dependency_error(self):
 
         class User(Base):
@@ -418,7 +418,7 @@ class DeclarativeTest(DeclarativeTestBase):
         Base = decl.declarative_base(cls=MyBase)
         assert hasattr(Base, 'metadata')
         assert Base().foobar() == "foobar"
-    
+
     def test_uses_get_on_class_col_fk(self):
 
         # test [ticket:1492]
@@ -454,27 +454,27 @@ class DeclarativeTest(DeclarativeTestBase):
             assert d1.master
 
         self.assert_sql_count(testing.db, go, 0)
-        
+
     def test_index_doesnt_compile(self):
         class User(Base):
             __tablename__ = 'users'
             id = Column('id', Integer, primary_key=True)
             name = Column('name', String(50))
             error = relationship("Address")
-            
+
         i = Index('my_index', User.name)
-        
+
         # compile fails due to the nonexistent Addresses relationship
         assert_raises(sa.exc.InvalidRequestError, configure_mappers)
-        
+
         # index configured
         assert i in User.__table__.indexes
         assert User.__table__.c.id not in set(i.columns)
         assert User.__table__.c.name in set(i.columns)
-        
+
         # tables create fine
         Base.metadata.create_all()
-        
+
     def test_add_prop(self):
 
         class User(Base, ComparableEntity):
@@ -510,7 +510,7 @@ class DeclarativeTest(DeclarativeTestBase):
         a1 = sess.query(Address).filter(Address.email == 'two').one()
         eq_(a1, Address(email='two'))
         eq_(a1.user, User(name='u1'))
-    
+
     def test_eager_order_by(self):
 
         class Address(Base, ComparableEntity):
@@ -613,7 +613,7 @@ class DeclarativeTest(DeclarativeTestBase):
             __tablename__ = 'foo'
             __mapper_cls__ = mymapper
             id = Column(Integer, primary_key=True)
-        
+
         eq_(Foo.__mapper__.CHECK, True)
 
     def test_custom_mapper_argument(self):
@@ -648,7 +648,7 @@ class DeclarativeTest(DeclarativeTestBase):
         assert_raises_message(sa.exc.ArgumentError,
                               'Mapper Mapper|User|users could not '
                               'assemble any primary key', define)
-        
+
     def test_table_args_bad_format(self):
 
         def err():
@@ -661,7 +661,7 @@ class DeclarativeTest(DeclarativeTestBase):
 
         assert_raises_message(sa.exc.ArgumentError,
                               'Tuple form of __table_args__ is ', err)
-        
+
     def test_table_args_type(self):
         def err():
             class Foo1(Base):
@@ -672,9 +672,9 @@ class DeclarativeTest(DeclarativeTestBase):
                 id = Column('id', Integer, primary_key=True)
         assert_raises_message(sa.exc.ArgumentError,
                               '__table_args__ value must be a tuple, ', err)
-            
+
     def test_table_args_none(self):
-            
+
         class Foo2(Base):
 
             __tablename__ = 'foo'
@@ -682,9 +682,9 @@ class DeclarativeTest(DeclarativeTestBase):
             id = Column('id', Integer, primary_key=True)
 
         assert Foo2.__table__.kwargs == {}
-        
+
     def test_table_args_dict_format(self):
-            
+
         class Foo2(Base):
 
             __tablename__ = 'foo'
@@ -758,14 +758,14 @@ class DeclarativeTest(DeclarativeTestBase):
                         test_needs_autoincrement=True)
             name = Column('name', String(50))
             addresses = relationship('Address', backref='user')
-            
+
             @declared_attr
             def address_count(cls):
                 # this doesn't really gain us anything.  but if
                 # one is used, lets have it function as expected...
                 return sa.orm.column_property(sa.select([sa.func.count(Address.id)]).
                         where(Address.user_id == cls.id))
-            
+
         Base.metadata.create_all()
         u1 = User(name='u1', addresses=[Address(email='one'),
                   Address(email='two')])
@@ -775,7 +775,7 @@ class DeclarativeTest(DeclarativeTestBase):
         sess.expunge_all()
         eq_(sess.query(User).all(), [User(name='u1', address_count=2,
             addresses=[Address(email='one'), Address(email='two')])])
-        
+
     def test_column(self):
 
         class User(Base, ComparableEntity):
@@ -873,7 +873,7 @@ class DeclarativeTest(DeclarativeTestBase):
             eq_(u1.name, 'u1')
 
         self.assert_sql_count(testing.db, go, 1)
-    
+
     def test_mapping_to_join(self):
         users = Table('users', Base.metadata,
             Column('id', Integer, primary_key=True)
@@ -887,16 +887,16 @@ class DeclarativeTest(DeclarativeTestBase):
         class User(Base):
             __table__ = usersaddresses
             __table_args__ = {'primary_key':[users.c.id]}
-            
+
             # need to use column_property for now
             user_id = column_property(users.c.id, addresses.c.user_id)
             address_id = addresses.c.id
-        
+
         assert User.__mapper__.get_property('user_id').columns[0] \
                                 is users.c.id
         assert User.__mapper__.get_property('user_id').columns[1] \
                                 is addresses.c.user_id
-        
+
     def test_synonym_inline(self):
 
         class User(Base, ComparableEntity):
@@ -1404,14 +1404,14 @@ class DeclarativeInheritanceTest(DeclarativeTestBase):
             primary_language = Column('primary_language', String(50))
 
         assert class_mapper(Engineer).inherits is class_mapper(Person)
-    
+
     @testing.fails_if(lambda: True, "Not implemented until 0.7")
     def test_foreign_keys_with_col(self):
         """Test that foreign keys that reference a literal 'id' subclass 
-        'id' attribute behave intuitively.  
-        
+        'id' attribute behave intuitively.
+
         See [ticket:1892].
-        
+
         """
         class Booking(Base):
             __tablename__ = 'booking'
@@ -1430,16 +1430,16 @@ class DeclarativeInheritanceTest(DeclarativeTestBase):
                                         primary_key=True)
             plan_booking_id = Column(Integer,
                                 ForeignKey(PlanBooking.id))
-            
+
             plan_booking = relationship(PlanBooking,
                         backref='feature_bookings')
-        
+
         assert FeatureBooking.__table__.c.plan_booking_id.\
                     references(PlanBooking.__table__.c.id)
 
         assert FeatureBooking.__table__.c.id.\
                     references(Booking.__table__.c.id)
-      
+
     def test_with_undefined_foreignkey(self):
 
         class Parent(Base):
@@ -1473,10 +1473,10 @@ class DeclarativeInheritanceTest(DeclarativeTestBase):
 
     def test_foreign_keys_with_col(self):
         """Test that foreign keys that reference a literal 'id' subclass 
-        'id' attribute behave intuitively.  
-        
+        'id' attribute behave intuitively.
+
         See [ticket:1892].
-        
+
         """
         class Booking(Base):
             __tablename__ = 'booking'
@@ -1495,16 +1495,16 @@ class DeclarativeInheritanceTest(DeclarativeTestBase):
                                         primary_key=True)
             plan_booking_id = Column(Integer,
                                 ForeignKey(PlanBooking.id))
-            
+
             plan_booking = relationship(PlanBooking,
                         backref='feature_bookings')
-        
+
         assert FeatureBooking.__table__.c.plan_booking_id.\
                     references(PlanBooking.__table__.c.id)
 
         assert FeatureBooking.__table__.c.id.\
                     references(Booking.__table__.c.id)
-      
+
 
     def test_single_colsonbase(self):
         """test single inheritance where all the columns are on the base
@@ -1562,9 +1562,9 @@ class DeclarativeInheritanceTest(DeclarativeTestBase):
     def test_single_colsonsub(self):
         """test single inheritance where the columns are local to their
         class.
-        
+
         this is a newer usage.
-        
+
         """
 
         class Company(Base, ComparableEntity):
@@ -1718,7 +1718,7 @@ class DeclarativeInheritanceTest(DeclarativeTestBase):
     def test_single_fksonsub(self):
         """test single inheritance with a foreign key-holding column on
         a subclass.
-        
+
         """
 
         class Person(Base, ComparableEntity):
@@ -2274,28 +2274,28 @@ class DeclarativeMixinTest(DeclarativeTestBase):
         eq_(obj.name, 'testing')
         eq_(obj.foo(), 'bar1')
         eq_(obj.baz, 'fu')
-    
+
     def test_mixin_overrides(self):
         """test a mixin that overrides a column on a superclass."""
-        
+
         class MixinA(object):
             foo = Column(String(50))
-        
+
         class MixinB(MixinA):
             foo = Column(Integer)
 
         class MyModelA(Base, MixinA):
             __tablename__ = 'testa'
             id = Column(Integer, primary_key=True)
-        
+
         class MyModelB(Base, MixinB):
             __tablename__ = 'testb'
             id = Column(Integer, primary_key=True)
-        
+
         eq_(MyModelA.__table__.c.foo.type.__class__, String)
         eq_(MyModelB.__table__.c.foo.type.__class__, Integer)
-        
-        
+
+
     def test_not_allowed(self):
 
         class MyMixin:
@@ -2347,7 +2347,7 @@ class DeclarativeMixinTest(DeclarativeTestBase):
             pass
 
         eq_(MyModel.__table__.name, 'mymodel')
-    
+
     def test_classproperty_still_works(self):
         class MyMixin(object):
             @classproperty
@@ -2359,7 +2359,7 @@ class DeclarativeMixinTest(DeclarativeTestBase):
             __tablename__ = 'overridden'
 
         eq_(MyModel.__table__.name, 'overridden')
-            
+
     def test_table_name_not_inherited(self):
 
         class MyMixin:
@@ -2449,13 +2449,13 @@ class DeclarativeMixinTest(DeclarativeTestBase):
         mapped to a superclass and single-table inheritance subclass.
         The superclass table gets the column, the subclass shares
         the MapperProperty.
-        
+
         """
-        
+
         class MyMixin(object):
             foo = Column('foo', Integer)
             bar = Column('bar_newname', Integer)
-            
+
         class General(Base, MyMixin):
             __tablename__ = 'test'
             id = Column(Integer, primary_key=True)
@@ -2468,19 +2468,19 @@ class DeclarativeMixinTest(DeclarativeTestBase):
         assert General.bar.prop.columns[0] is General.__table__.c.bar_newname
         assert len(General.bar.prop.columns) == 1
         assert Specific.bar.prop is General.bar.prop
-        
+
     def test_columns_joined_table_inheritance(self):
         """Test a column on a mixin with an alternate attribute name,
         mapped to a superclass and joined-table inheritance subclass.
         Both tables get the column, in the case of the subclass the two
         columns are joined under one MapperProperty.
-        
+
         """
 
         class MyMixin(object):
             foo = Column('foo', Integer)
             bar = Column('bar_newname', Integer)
-            
+
         class General(Base, MyMixin):
             __tablename__ = 'test'
             id = Column(Integer, primary_key=True)
@@ -2498,7 +2498,7 @@ class DeclarativeMixinTest(DeclarativeTestBase):
         assert len(Specific.bar.prop.columns) == 2
         assert Specific.bar.prop.columns[0] is General.__table__.c.bar_newname
         assert Specific.bar.prop.columns[1] is Specific.__table__.c.bar_newname
-    
+
     def test_column_join_checks_superclass_type(self):
         """Test that the logic which joins subclass props to those
         of the superclass checks that the superclass property is a column.
@@ -2514,7 +2514,7 @@ class DeclarativeMixinTest(DeclarativeTestBase):
             __tablename__ = 'sub'
             id = Column(Integer, ForeignKey('test.id'), primary_key=True)
             type_ = Column('foob', String(50))
-        
+
         assert isinstance(General.type_.property, sa.orm.RelationshipProperty)
         assert Specific.type_.property.columns[0] is Specific.__table__.c.foob
 
@@ -2537,7 +2537,7 @@ class DeclarativeMixinTest(DeclarativeTestBase):
         assert_raises_message(
             sa.exc.ArgumentError, "column 'foob' conflicts with property", go
         )
-        
+
     def test_table_args_overridden(self):
 
         class MyMixin:
@@ -2712,13 +2712,13 @@ class DeclarativeMixinTest(DeclarativeTestBase):
                 if cls.__name__ != 'MyModel':
                     args.pop('polymorphic_on')
                     args['polymorphic_identity'] = cls.__name__
-                    
+
                 return args
             id = Column(Integer, primary_key=True)
-        
+
         class MySubModel(MyModel):
             pass
-        
+
         eq_(
             MyModel.__mapper__.polymorphic_on.name, 
             'type_'
@@ -2727,32 +2727,32 @@ class DeclarativeMixinTest(DeclarativeTestBase):
         eq_(MyModel.__mapper__.always_refresh, True)
         eq_(MySubModel.__mapper__.always_refresh, True)
         eq_(MySubModel.__mapper__.polymorphic_identity, 'MySubModel')
-    
+
     def test_mapper_args_property(self):
         class MyModel(Base):
-            
+
             @declared_attr
             def __tablename__(cls):
                 return cls.__name__.lower()
-            
+
             @declared_attr
             def __table_args__(cls):
                 return {'mysql_engine':'InnoDB'}
-                
+
             @declared_attr
             def __mapper_args__(cls):
                 args = {}
                 args['polymorphic_identity'] = cls.__name__
                 return args
             id = Column(Integer, primary_key=True)
-        
+
         class MySubModel(MyModel):
             id = Column(Integer, ForeignKey('mymodel.id'), primary_key=True)
 
         class MySubModel2(MyModel):
             __tablename__ = 'sometable'
             id = Column(Integer, ForeignKey('mymodel.id'), primary_key=True)
-        
+
         eq_(MyModel.__mapper__.polymorphic_identity, 'MyModel')
         eq_(MySubModel.__mapper__.polymorphic_identity, 'MySubModel')
         eq_(MyModel.__table__.kwargs['mysql_engine'], 'InnoDB')
@@ -2760,37 +2760,37 @@ class DeclarativeMixinTest(DeclarativeTestBase):
         eq_(MySubModel2.__table__.kwargs['mysql_engine'], 'InnoDB')
         eq_(MyModel.__table__.name, 'mymodel')
         eq_(MySubModel.__table__.name, 'mysubmodel')
-    
+
     def test_mapper_args_custom_base(self):
         """test the @declared_attr approach from a custom base."""
-        
+
         class Base(object):
             @declared_attr
             def __tablename__(cls):
                 return cls.__name__.lower()
-            
+
             @declared_attr
             def __table_args__(cls):
                 return {'mysql_engine':'InnoDB'}
-            
+
             @declared_attr
             def id(self):
                 return Column(Integer, primary_key=True)
-            
+
         Base = decl.declarative_base(cls=Base)
-        
+
         class MyClass(Base):
             pass
-        
+
         class MyOtherClass(Base):
             pass
-            
+
         eq_(MyClass.__table__.kwargs['mysql_engine'], 'InnoDB')
         eq_(MyClass.__table__.name, 'myclass')
         eq_(MyOtherClass.__table__.name, 'myotherclass')
         assert MyClass.__table__.c.id.table is MyClass.__table__
         assert MyOtherClass.__table__.c.id.table is MyOtherClass.__table__
-        
+
     def test_single_table_no_propagation(self):
 
         class IdColumn:
@@ -2979,7 +2979,7 @@ class DeclarativeMixinTest(DeclarativeTestBase):
 
         class ColumnMixin:
             tada = Column(Integer)
-            
+
         def go():
 
             class Model(Base, ColumnMixin):
@@ -2988,20 +2988,20 @@ class DeclarativeMixinTest(DeclarativeTestBase):
                                 Column('data',Integer), 
                                 Column('id', Integer,primary_key=True))
                 foo = relationship("Dest")
-                
+
         assert_raises_message(sa.exc.ArgumentError,
                               "Can't add additional column 'tada' when "
                               "specifying __table__", go)
 
     def test_table_in_model_and_different_named_alt_key_column_in_mixin(self):
-        
+
         # here, the __table__ has a column 'tada'.  We disallow
         # the add of the 'foobar' column, even though it's
         # keyed to 'tada'.
-        
+
         class ColumnMixin:
             tada = Column('foobar', Integer)
-            
+
         def go():
 
             class Model(Base, ColumnMixin):
@@ -3011,7 +3011,7 @@ class DeclarativeMixinTest(DeclarativeTestBase):
                                 Column('tada', Integer),
                                 Column('id', Integer,primary_key=True))
                 foo = relationship("Dest")
-                
+
         assert_raises_message(sa.exc.ArgumentError,
                               "Can't add additional column 'foobar' when "
                               "specifying __table__", go)
@@ -3098,10 +3098,10 @@ class DeclarativeMixinPropertyTest(DeclarativeTestBase):
 
     def test_doc(self):
         """test documentation transfer.
-        
+
         the documentation situation with @declared_attr is problematic.
         at least see if mapped subclasses get the doc.
-        
+
         """
 
         class MyMixin(object):
@@ -3224,4 +3224,4 @@ class DeclarativeMixinPropertyTest(DeclarativeTestBase):
 
     def test_relationship_primryjoin(self):
         self._test_relationship(True)
-        
+
index b4f60519c629dac0b45a1934be6e552eeac2bab9..f2b56bca899f1bd4a16d0fc2341ed6d83736b6e6 100644 (file)
@@ -29,7 +29,7 @@ class ShardTest(TestBase):
 
         def id_generator(ctx):
             # in reality, might want to use a separate transaction for this.
-            
+
             c = db1.contextual_connect()
             nextid = c.execute(ids.select(for_update=True)).scalar()
             c.execute(ids.update(values={ids.c.nextid : ids.c.nextid + 1}))
index 3dfd4c8568fd095216be4abe2e355d4c47c6cd81..46fc01aae7de3168b5cb036a6fefcceaa0df4774 100644 (file)
@@ -23,7 +23,7 @@ Base = declarative_base()
 
 
 class UCComparator(hybrid.Comparator):
-    
+
     def __eq__(self, other):
         if other is None:
             return self.expression == None
@@ -42,7 +42,7 @@ class A(Base):
     @value.comparator
     def value(cls):
         return UCComparator(cls._value)
-        
+
     @value.setter
     def value(self, v):
         self.value = v
@@ -73,7 +73,7 @@ class A(Base):
     @hybrid.property
     def value(self):
         return int(self._value)
-    
+
     @value.expression
     def value(cls):
         return func.foo(cls._value) + cls.bar_value
@@ -85,7 +85,7 @@ class A(Base):
     @hybrid.property
     def bar_value(cls):
         return func.bar(cls._value)
-        
+
 #print A.value
 #print A.value.__doc__
 
index 1d8208743f16855ea0037c444db4359c52b3f8e3..9ae28a7fc6883e0cd26eca02e6502405113d9bc4 100644 (file)
@@ -13,10 +13,10 @@ class _MutableDictTestBase(object):
     @classmethod
     def _type_fixture(cls):
         from sqlalchemy.ext.mutable import Mutable
-        
+
         # needed for pickle support
         global MutationDict
-        
+
         class MutationDict(Mutable, dict):
             @classmethod
             def coerce(cls, key, value):
@@ -26,27 +26,27 @@ class _MutableDictTestBase(object):
                     return Mutable.coerce(key, value)
                 else:
                     return value
-        
+
             def __getstate__(self):
                 return dict(self)
-        
+
             def __setstate__(self, dict):
                 self.update(dict)
-            
+
             def __setitem__(self, key, value):
                 dict.__setitem__(self, key, value)
                 self.change()
-    
+
             def __delitem__(self, key):
                 dict.__delitem__(self, key)
                 self.change()
         return MutationDict
-    
+
     @testing.resolve_artifact_names
     def setup_mappers(cls):
         class Foo(_base.BasicEntity):
             pass
-        
+
         mapper(Foo, foo)
 
     def teardown(self):
@@ -54,7 +54,7 @@ class _MutableDictTestBase(object):
         Mapper.dispatch._clear()
         ClassManager.dispatch._clear()
         super(_MutableDictTestBase, self).teardown()
-        
+
     @testing.resolve_artifact_names
     def test_in_place_mutation(self):
         sess = Session()
@@ -85,16 +85,16 @@ class MutableWithScalarPickleTest(_MutableDictTestBase, _base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
         MutationDict = cls._type_fixture()
-        
+
         Table('foo', metadata,
             Column('id', Integer, primary_key=True, test_needs_pk=True),
             Column('data', MutationDict.as_mutable(PickleType)),
             Column('non_mutable_data', PickleType)
         )
-    
+
     def test_non_mutable(self):
         self._test_non_mutable()
-        
+
 class MutableWithScalarJSONTest(_MutableDictTestBase, _base.MappedTest):
     # json introduced in 2.6
     __skip_if__ = lambda : sys.version_info < (2, 6),
@@ -116,7 +116,7 @@ class MutableWithScalarJSONTest(_MutableDictTestBase, _base.MappedTest):
                 if value is not None:
                     value = json.loads(value)
                 return value
-        
+
         MutationDict = cls._type_fixture()
 
         Table('foo', metadata,
@@ -133,7 +133,7 @@ class MutableAssociationScalarPickleTest(_MutableDictTestBase, _base.MappedTest)
     def define_tables(cls, metadata):
         MutationDict = cls._type_fixture()
         MutationDict.associate_with(PickleType)
-        
+
         Table('foo', metadata,
             Column('id', Integer, primary_key=True, test_needs_pk=True),
             Column('data', PickleType)
@@ -163,12 +163,12 @@ class MutableAssociationScalarJSONTest(_MutableDictTestBase, _base.MappedTest):
 
         MutationDict = cls._type_fixture()
         MutationDict.associate_with(JSONEncodedDict)
-        
+
         Table('foo', metadata,
             Column('id', Integer, primary_key=True, test_needs_pk=True),
             Column('data', JSONEncodedDict)
         )
-        
+
 class MutableCompositesTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -186,12 +186,12 @@ class MutableCompositesTest(_base.MappedTest):
 
     @classmethod
     def _type_fixture(cls):
-        
+
         from sqlalchemy.ext.mutable import Mutable
         from sqlalchemy.ext.mutable import MutableComposite
-        
+
         global Point
-        
+
         class Point(MutableComposite):
             def __init__(self, x, y):
                 self.x = x
@@ -200,24 +200,24 @@ class MutableCompositesTest(_base.MappedTest):
             def __setattr__(self, key, value):
                 object.__setattr__(self, key, value)
                 self.change()
-        
+
             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
         return Point
-        
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_mappers(cls):
         Point = cls._type_fixture()
-        
+
         class Foo(_base.BasicEntity):
             pass
-            
+
         mapper(Foo, foo, properties={
             'data':composite(Point, foo.c.x, foo.c.y)
         })
@@ -235,4 +235,3 @@ class MutableCompositesTest(_base.MappedTest):
 
         eq_(f1.data, Point(3, 5))
 
-                
\ No newline at end of file
index 66f7030684143bddbdb3cd5793afe9479ce1e9c7..dfee5748ff87760c0e14be87eb00c56b5a825df9 100644 (file)
@@ -43,7 +43,7 @@ class SQLSoupTest(TestBase):
 
     def test_map_to_table_not_string(self):
         db = sqlsoup.SqlSoup(engine)
-        
+
         table = Table('users', db._metadata, Column('id', Integer, primary_key=True))
         assert_raises_message(
             exc.ArgumentError,
index b206f91fc9fabedbc6a8cb283bc4225b3ea333ee..4954a0bfed6b6643d24ddf201608d720363dd299 100644 (file)
@@ -16,10 +16,10 @@ class AssertRule(object):
 
     def is_consumed(self):
         """Return True if this rule has been consumed, False if not.
-        
+
         Should raise an AssertionError if this rule's condition has
         definitely failed.
-        
+
         """
 
         raise NotImplementedError()
@@ -32,10 +32,10 @@ class AssertRule(object):
 
     def consume_final(self):
         """Return True if this rule has been consumed.
-        
+
         Should raise an AssertionError if this rule's condition has not
         been consumed or has failed.
-        
+
         """
 
         if self._result is None:
@@ -46,18 +46,18 @@ class SQLMatchRule(AssertRule):
     def __init__(self):
         self._result = None
         self._errmsg = ""
-    
+
     def rule_passed(self):
         return self._result
-        
+
     def is_consumed(self):
         if self._result is None:
             return False
-            
+
         assert self._result, self._errmsg
-        
+
         return True
-    
+
 class ExactSQL(SQLMatchRule):
 
     def __init__(self, sql, params=None):
@@ -96,7 +96,7 @@ class ExactSQL(SQLMatchRule):
                 'Testing for exact statement %r exact params %r, '\
                 'received %r with params %r' % (sql, params,
                     _received_statement, _received_parameters)
-    
+
 
 class RegexSQL(SQLMatchRule):
 
@@ -194,7 +194,7 @@ class CompiledSQL(SQLMatchRule):
 
 
             # print self._errmsg
-    
+
 class CountStatements(AssertRule):
 
     def __init__(self, count):
@@ -216,7 +216,7 @@ class CountStatements(AssertRule):
             'desired statement count %d does not match %d' \
             % (self.count, self._statement_count)
         return True
-        
+
 class AllOf(AssertRule):
 
     def __init__(self, *rules):
@@ -243,7 +243,7 @@ class AllOf(AssertRule):
 
     def consume_final(self):
         return len(self.rules) == 0
-        
+
 def _process_engine_statement(query, context):
     if util.jython:
 
@@ -255,7 +255,7 @@ def _process_engine_statement(query, context):
         query = query[:-25]
     query = re.sub(r'\n', '', query)
     return query
-    
+
 def _process_assertion_statement(query, context):
     paramstyle = context.dialect.paramstyle
     if paramstyle == 'named':
@@ -311,4 +311,4 @@ class SQLAssert(object):
                     executemany)
 
 asserter = SQLAssert()
-    
+
index 60272839bd56870035562c1685b0afb8b9867062..1c97e23cfca8b44b595d5dcfa014c5a44d4789b1 100644 (file)
@@ -65,11 +65,11 @@ def rollback_open_connections(fn, *args, **kw):
 @decorator
 def close_first(fn, *args, **kw):
     """Decorator that closes all connections before fn execution."""
-    
+
     testing_reaper.close_all()
     fn(*args, **kw)
-    
-    
+
+
 @decorator
 def close_open_connections(fn, *args, **kw):
     """Decorator that closes all connections after fn execution."""
@@ -88,7 +88,7 @@ def all_dialects(exclude=None):
         if not mod:
             mod = getattr(__import__('sqlalchemy.databases.%s' % name).databases, name)
         yield mod.dialect()
-        
+
 class ReconnectFixture(object):
     def __init__(self, dbapi):
         self.dbapi = dbapi
@@ -135,11 +135,11 @@ def testing_engine(url=None, options=None):
     event.listen(engine, 'after_execute', asserter.execute)
     event.listen(engine, 'after_cursor_execute', asserter.cursor_execute)
     event.listen(engine.pool, 'checkout', testing_reaper.checkout)
-    
+
     # may want to call this, results
     # in first-connect initializers
     #engine.connect()
-    
+
     return engine
 
 def utf8_engine(url=None, options=None):
@@ -165,18 +165,18 @@ def utf8_engine(url=None, options=None):
 
 def mock_engine(dialect_name=None):
     """Provides a mocking engine based on the current testing.db.
-    
+
     This is normally used to test DDL generation flow as emitted
     by an Engine.
-    
+
     It should not be used in other cases, as assert_compile() and
     assert_sql_execution() are much better choices with fewer 
     moving parts.
-    
+
     """
-    
+
     from sqlalchemy import create_engine
-    
+
     if not dialect_name:
         dialect_name = config.db.name
 
@@ -186,7 +186,7 @@ def mock_engine(dialect_name=None):
     def assert_sql(stmts):
         recv = [re.sub(r'[\n\t]', '', str(s)) for s in buffer]
         assert  recv == stmts, recv
-        
+
     engine = create_engine(dialect_name + '://',
                            strategy='mock', executor=executor)
     assert not hasattr(engine, 'mock')
@@ -212,7 +212,7 @@ class ReplayableSession(object):
                             #for t in ('FunctionType', 'BuiltinFunctionType',
                             #          'MethodType', 'BuiltinMethodType',
                             #          'LambdaType', )])
-                            
+
                             # Py2K
                                for t in ('FunctionType', 'BuiltinFunctionType',
                                          'MethodType', 'BuiltinMethodType',
@@ -243,11 +243,11 @@ class ReplayableSession(object):
             else:
                 buffer.append(result)
                 return result
-        
+
         @property
         def _sqla_unwrap(self):
             return self._subject
-            
+
         def __getattribute__(self, key):
             try:
                 return object.__getattribute__(self, key)
@@ -280,11 +280,11 @@ class ReplayableSession(object):
                 return self
             else:
                 return result
-        
+
         @property
         def _sqla_unwrap(self):
             return None
-            
+
         def __getattribute__(self, key):
             try:
                 return object.__getattribute__(self, key)
index 0ec677eeadff9b12a15ed1047de41ec7382b5908..1b24e73b7cdcdc3e330600b2d62a87c2efa6d969 100644 (file)
@@ -50,7 +50,7 @@ class ComparableEntity(BasicEntity):
                 self_key = sa.orm.attributes.instance_state(self).key
             except sa.orm.exc.NO_STATE:
                 self_key = None
-                
+
             if other is None:
                 a = self
                 b = other
index 9794e424db4e783948110cd9671da002b609ab68..acc07ceba88ff23866ed8bb9a113427e829f4146 100644 (file)
@@ -33,11 +33,11 @@ class OldSchool:
     def __eq__(self, other):
         return other.__class__ is self.__class__ and other.x==self.x and other.y==self.y
 
-class OldSchoolWithoutCompare:    
+class OldSchoolWithoutCompare:
     def __init__(self, x, y):
         self.x = x
         self.y = y
-    
+
 class BarWithoutCompare(object):
     def __init__(self, x, y):
         self.x = x
index 8676adf019d4b83e0f574eaf38e8f183a8a24d35..bac9e549fee328a0360f91ba57bd7734e798cf9d 100644 (file)
@@ -41,7 +41,7 @@ def profiled(target=None, **target_opts):
     all_targets.add(target)
 
     filename = "%s.prof" % target
-    
+
     @decorator
     def decorate(fn, *args, **kw):
         if (target not in profile_config['targets'] and
@@ -50,7 +50,7 @@ def profiled(target=None, **target_opts):
 
         elapsed, load_stats, result = _profile(
             filename, fn, *args, **kw)
-        
+
         graphic = target_opts.get('graphic', profile_config['graphic'])
         if graphic:
             os.system("runsnake %s" % filename)
@@ -68,17 +68,17 @@ def profiled(target=None, **target_opts):
                     stats.print_stats(limit)
                 else:
                     stats.print_stats()
-            
+
                 print_callers = target_opts.get('print_callers', 
                                                 profile_config['print_callers'])
                 if print_callers:
                     stats.print_callers()
-            
+
                 print_callees = target_opts.get('print_callees', 
                                                 profile_config['print_callees'])
                 if print_callees:
                     stats.print_callees()
-                
+
         os.unlink(filename)
         return result
     return decorate
@@ -113,7 +113,7 @@ def function_call_count(count=None, versions={}, variance=0.05):
         cextension = True
     except ImportError:
         cextension = False
-    
+
     while version_info:
         version = '.'.join([str(v) for v in version_info])
         if cextension and (version + "+cextension") in versions:
@@ -129,7 +129,7 @@ def function_call_count(count=None, versions={}, variance=0.05):
     if count is None:
         print "Warning: no function call count specified for version: '%s'" % py_version
         return lambda fn: fn
-    
+
     @decorator
     def decorate(fn, *args, **kw):
         try:
index 222dc93f6f2a06cb4c79ac6d7a5f399f1affc15d..993a1546f516921e86bc99de4d770f4e9c308fde 100644 (file)
@@ -54,7 +54,7 @@ def boolean_col_expressions(fn):
         no_support('maxdb', 'FIXME: verify not supported by database'),
         no_support('informix', 'not supported by database'),
     )
-    
+
 def identity(fn):
     """Target database must support GENERATED AS IDENTITY or a facsimile.
 
@@ -99,19 +99,19 @@ def row_triggers(fn):
         # no access to same table
         no_support('mysql', 'requires SUPER priv'),
         exclude('mysql', '<', (5, 0, 10), 'not supported by database'),
-        
+
         # huh?  TODO: implement triggers for PG tests, remove this
-        no_support('postgresql', 'PG triggers need to be implemented for tests'),  
+        no_support('postgresql', 'PG triggers need to be implemented for tests'),
         )
 
 def correlated_outer_joins(fn):
     """Target must support an outer join to a subquery which correlates to the parent."""
-    
+
     return _chain_decorators_on(
         fn,
         no_support('oracle', 'Raises "ORA-01799: a column may not be outer-joined to a subquery"')
     )
-    
+
 def savepoints(fn):
     """Target database must support savepoints."""
     return _chain_decorators_on(
@@ -126,21 +126,21 @@ def savepoints(fn):
 
 def denormalized_names(fn):
     """Target database must have 'denormalized', i.e. UPPERCASE as case insensitive names."""
-    
+
     return skip_if(
                 lambda: not testing.db.dialect.requires_name_normalize,
                 "Backend does not require denomralized names."
             )(fn)
-    
+
 def schemas(fn):
     """Target database must support external schemas, and have one named 'test_schema'."""
-    
+
     return _chain_decorators_on(
         fn,
         no_support('sqlite', 'no schema support'),
         no_support('firebird', 'no schema support')
     )
-    
+
 def sequences(fn):
     """Target database must support SEQUENCEs."""
     return _chain_decorators_on(
@@ -164,7 +164,7 @@ def update_nowait(fn):
         no_support('sqlite', 'no FOR UPDATE NOWAIT support'),
         no_support('sybase', 'no FOR UPDATE NOWAIT support'),
     )
-    
+
 def subqueries(fn):
     """Target database must support subqueries."""
     return _chain_decorators_on(
@@ -198,7 +198,7 @@ def offset(fn):
         fn,
         fails_on('sybase', 'no support for OFFSET or equivalent'),
     )
-    
+
 def returning(fn):
     return _chain_decorators_on(
         fn,
@@ -209,7 +209,7 @@ def returning(fn):
         no_support('sybase', 'not supported by database'),
         no_support('informix', 'not supported by database'),
     )
-    
+
 def two_phase_transactions(fn):
     """Target database must support two-phase transactions."""
     return _chain_decorators_on(
@@ -257,13 +257,13 @@ def cextensions(fn):
         fn,
         skip_if(lambda: not _has_cextensions(), "C extensions not installed")
     )
-    
+
 def dbapi_lastrowid(fn):
     return _chain_decorators_on(
         fn,
         fails_on_everything_except('mysql+mysqldb', 'mysql+oursql', 'sqlite+pysqlite')
     )
-    
+
 def sane_multi_rowcount(fn):
     return _chain_decorators_on(
         fn,
@@ -283,7 +283,7 @@ def reflects_pk_names(fn):
         fn,
         fails_on_everything_except('postgresql', 'oracle')
     )
-    
+
 def python2(fn):
     return _chain_decorators_on(
         fn,
@@ -317,7 +317,7 @@ def _has_cextensions():
         return True
     except ImportError:
         return False
-        
+
 def _has_sqlite():
     from sqlalchemy import create_engine
     try:
index 614e5863eb66904561e265a18bdfe04c314ccc63..b4aabfe76cdcca033ea940a9bae6954b57c576e8 100644 (file)
@@ -76,4 +76,4 @@ def _truncate_name(dialect, name):
         return name[0:max(dialect.max_identifier_length - 6, 0)] + "_" + hex(hash(name) % 64)[2:]
     else:
         return name
-    
+
index 6a2c62959e4bca5478535c82221228839beca9e1..d6338cf10f2da64c174d16ea39666e74017a72a2 100644 (file)
@@ -18,7 +18,7 @@ from sqlalchemy import exc as sa_exc, util, types as sqltypes, schema, \
 from sqlalchemy.engine import default
 from nose import SkipTest
 
-    
+
 _ops = { '<': operator.lt,
          '>': operator.gt,
          '==': operator.eq,
@@ -90,9 +90,9 @@ def db_spec(*dbs):
         return engine.name in dialects or \
             engine.driver in drivers or \
             (engine.name, engine.driver) in specs
-    
+
     return check
-        
+
 
 def fails_on(dbs, reason):
     """Mark a test as expected to fail on the specified database 
@@ -105,7 +105,7 @@ def fails_on(dbs, reason):
     """
 
     spec = db_spec(dbs)
-    
+
     @decorator
     def decorate(fn, *args, **kw):
         if not spec(config.db):
@@ -132,7 +132,7 @@ def fails_on_everything_except(*dbs):
     """
 
     spec = db_spec(*dbs)
-    
+
     @decorator
     def decorate(fn, *args, **kw):
         if spec(config.db):
@@ -211,7 +211,7 @@ def only_on(dbs, reason):
                 print >> sys.stderr, msg
             return True
     return decorate
-    
+
 def exclude(db, op, spec, reason):
     """Mark a test as unsupported by specific database server versions.
 
@@ -225,7 +225,7 @@ def exclude(db, op, spec, reason):
 
     """
     carp = _should_carp_about_exclusion(reason)
-    
+
     @decorator
     def decorate(fn, *args, **kw):
         if _is_excluded(db, op, spec):
@@ -283,7 +283,7 @@ def _server_version(bind=None):
 
     if bind is None:
         bind = config.db
-    
+
     # force metadata to be retrieved
     conn = bind.connect()
     version = getattr(bind.dialect, 'server_version_info', ())
@@ -294,7 +294,7 @@ def skip_if(predicate, reason=None):
     """Skip a test if predicate is true."""
     reason = reason or predicate.__name__
     carp = _should_carp_about_exclusion(reason)
-    
+
     @decorator
     def decorate(fn, *args, **kw):
         if predicate():
@@ -320,7 +320,7 @@ def emits_warning(*messages):
     # and may work on non-CPython if they keep to the spirit of
     # warnings.showwarning's docstring.
     # - update: jython looks ok, it uses cpython's module
-    
+
     @decorator
     def decorate(fn, *args, **kw):
         # todo: should probably be strict about this, too
@@ -350,7 +350,7 @@ def emits_warning_on(db, *warnings):
     warnings.filterwarnings().
     """
     spec = db_spec(db)
-    
+
     @decorator
     def decorate(fn, *args, **kw):
         if isinstance(db, basestring):
@@ -369,16 +369,16 @@ def emits_warning_on(db, *warnings):
 
 def assert_warnings(fn, warnings):
     """Assert that each of the given warnings are emitted by fn."""
-    
+
     orig_warn = util.warn
     def capture_warnings(*args, **kw):
         orig_warn(*args, **kw)
         popwarn = warnings.pop(0)
         eq_(args[0], popwarn)
     util.warn = util.langhelpers.warn = capture_warnings
-    
+
     return emits_warning()(fn)()
-    
+
 def uses_deprecated(*messages):
     """Mark a test as immune from fatal deprecation warnings.
 
@@ -419,7 +419,7 @@ def uses_deprecated(*messages):
 
 def testing_warn(msg, stacklevel=3):
     """Replaces sqlalchemy.util.warn during tests."""
-    
+
     filename = "test.lib.testing"
     lineno = 1
     if isinstance(msg, basestring):
@@ -429,9 +429,9 @@ def testing_warn(msg, stacklevel=3):
 
 def resetwarnings():
     """Reset warning behavior to testing defaults."""
-    
+
     util.warn = util.langhelpers.warn = testing_warn
-    
+
     warnings.filterwarnings('ignore',
                             category=sa_exc.SAPendingDeprecationWarning) 
     warnings.filterwarnings('error', category=sa_exc.SADeprecationWarning)
@@ -440,17 +440,17 @@ def resetwarnings():
 
 def global_cleanup_assertions():
     """Check things that have to be finalized at the end of a test suite.
-    
+
     Hardcoded at the moment, a modular system can be built here
     to support things like PG prepared transactions, tables all
     dropped, etc.
-    
+
     """
 
     testutil.lazy_gc()
     assert not pool._refs
-    
-    
+
+
 
 def against(*queries):
     """Boolean predicate, compares to testing database configuration.
@@ -523,7 +523,7 @@ def assert_raises(except_cls, callable_, *args, **kw):
         success = False
     except except_cls, e:
         success = True
-    
+
     # assert outside the block so it works for AssertionError too !
     assert success, "Callable did not raise an exception"
 
@@ -537,7 +537,7 @@ def assert_raises_message(except_cls, msg, callable_, *args, **kwargs):
 
 def fail(msg):
     assert False, msg
-    
+
 def fixture(table, columns, *rows):
     """Insert data into table after creation."""
     def onload(event, schema_item, connection):
@@ -624,34 +624,34 @@ class TestBase(object):
 
     def assert_(self, val, msg=None):
         assert val, msg
-        
+
 class AssertsCompiledSQL(object):
     def assert_compile(self, clause, result, params=None, checkparams=None, dialect=None, use_default_dialect=False):
         if use_default_dialect:
             dialect = default.DefaultDialect()
-            
+
         if dialect is None:
             dialect = getattr(self, '__dialect__', None)
 
         kw = {}
         if params is not None:
             kw['column_keys'] = params.keys()
-        
+
         if isinstance(clause, orm.Query):
             context = clause._compile_context()
             context.statement.use_labels = True
             clause = context.statement
-            
+
         c = clause.compile(dialect=dialect, **kw)
 
         param_str = repr(getattr(c, 'params', {}))
         # Py3K
         #param_str = param_str.encode('utf-8').decode('ascii', 'ignore')
-        
+
         print "\nSQL String:\n" + str(c) + param_str
-        
+
         cc = re.sub(r'[\n\t]', '', str(c))
-        
+
         eq_(cc, result, "%r != %r on dialect %r" % (cc, result, dialect))
 
         if checkparams is not None:
@@ -665,7 +665,7 @@ class ComparesTables(object):
             assert reflected_c is reflected_table.c[c.name]
             eq_(c.primary_key, reflected_c.primary_key)
             eq_(c.nullable, reflected_c.nullable)
-            
+
             if strict_types:
                 assert type(reflected_c.type) is type(c.type), \
                     "Type '%s' doesn't correspond to type '%s'" % (reflected_c.type, c.type)
@@ -683,7 +683,7 @@ class ComparesTables(object):
         assert len(table.primary_key) == len(reflected_table.primary_key)
         for c in table.primary_key:
             assert reflected_table.primary_key.columns[c.name] is not None
-    
+
     def assert_types_base(self, c1, c2):
         assert c1.type._compare_type_affinity(c2.type),\
                 "On column %r, type '%s' doesn't correspond to type '%s'" % \
@@ -770,13 +770,13 @@ class AssertsExecutionResults(object):
             assertsql.asserter.statement_complete()
         finally:
             assertsql.asserter.clear_rules()
-            
+
     def assert_sql(self, db, callable_, list_, with_sequences=None):
         if with_sequences is not None and config.db.name in ('firebird', 'oracle', 'postgresql'):
             rules = with_sequences
         else:
             rules = list_
-        
+
         newrules = []
         for rule in rules:
             if isinstance(rule, dict):
@@ -786,7 +786,7 @@ class AssertsExecutionResults(object):
             else:
                 newrule = assertsql.ExactSQL(*rule)
             newrules.append(newrule)
-            
+
         self.assert_sql_execution(db, callable_, *newrules)
 
     def assert_sql_count(self, db, callable_, count):
index 4c9892852f7a22432122115550319fcf3ee517ca..b512cf6b0a502df6101c43e28383635685f96a5f 100644 (file)
@@ -13,7 +13,7 @@ if jython:
         gc.collect()
         gc.collect()
         return 0
-        
+
     # "lazy" gc, for VM's that don't GC on refcount == 0
     lazy_gc = gc_collect
 
@@ -34,48 +34,48 @@ def picklers():
     # end Py2K
     import pickle
     picklers.add(pickle)
-    
+
     # yes, this thing needs this much testing
     for pickle in picklers:
         for protocol in -1, 0, 1, 2:
             yield pickle.loads, lambda d:pickle.dumps(d, protocol)
-    
-    
+
+
 def round_decimal(value, prec):
     if isinstance(value, float):
         return round(value, prec)
-    
+
     # can also use shift() here but that is 2.6 only
     return (value * decimal.Decimal("1" + "0" * prec)).to_integral(decimal.ROUND_FLOOR) / \
                         pow(10, prec)
-    
+
 class RandomSet(set):
     def __iter__(self):
         l = list(set.__iter__(self))
         random.shuffle(l)
         return iter(l)
-    
+
     def pop(self):
         index = random.randint(0, len(self) - 1)
         item = list(set.__iter__(self))[index]
         self.remove(item)
         return item
-        
+
     def union(self, other):
         return RandomSet(set.union(self, other))
-    
+
     def difference(self, other):
         return RandomSet(set.difference(self, other))
-        
+
     def intersection(self, other):
         return RandomSet(set.intersection(self, other))
-        
+
     def copy(self):
         return RandomSet(self)
-        
+
 def conforms_partial_ordering(tuples, sorted_elements):
     """True if the given sorting conforms to the given partial ordering."""
-    
+
     deps = defaultdict(set)
     for parent, child in tuples:
         deps[parent].add(child)
@@ -101,7 +101,7 @@ def all_partial_orderings(tuples, elements):
                 if not subset.intersection(edges[elem]):
                     for sub_ordering in _all_orderings(subset):
                         yield [elem] + sub_ordering
-    
+
     return iter(_all_orderings(elements))
 
 
@@ -114,7 +114,7 @@ def function_named(fn, name):
     This function should be phased out as much as possible
     in favor of @decorator.   Tests that "generate" many named tests
     should be modernized.
-    
+
     """
     try:
         fn.__name__ = name
index 345009d400839754e8a9fe802a21bbdd532a0780..ef1ec33f1311c3e356dbe43b97bc723748a54d91 100644 (file)
@@ -183,7 +183,7 @@ class MappedTest(ORMTest):
         if name[0].isupper:
             delattr(cls, name)
         del cls.classes[name]
-    
+
     @classmethod
     def _load_fixtures(cls):
         headers, rows = {}, {}
index 8f128c287d40212b1a811149c289e35b3dd1fae8..3c7d0aa57cbaef49fd0dbe085fe16d7f7fdd476b 100644 (file)
@@ -169,7 +169,7 @@ composite_pk_table = fixture_table(
     Table('composite_pk_table', fixture_metadata,
         Column('i', Integer, primary_key=True),
         Column('j', Integer, primary_key=True),
-        Column('k', Integer, nullable=False),                    
+        Column('k', Integer, nullable=False),
     ),
     ('i', 'j', 'k'),
     (1, 2, 3),
@@ -218,7 +218,7 @@ class Node(Base):
 
 class CompositePk(Base):
     pass
-    
+
 class FixtureTest(_base.MappedTest):
     """A MappedTest pre-configured for fixtures.
 
@@ -378,7 +378,7 @@ class CannedResults(object):
                  keywords=[]),
             Item(id=5,
                  keywords=[])]
-    
+
     @property
     def user_item_keyword_result(self):
         item1, item2, item3, item4, item5 = \
@@ -420,6 +420,6 @@ class CannedResults(object):
                            items=[item1, item5])]),
                 User(id=10, orders=[])]
         return user_result
-        
+
 FixtureTest.static = CannedResults()
 
index 08ab28a089a5866a0ad8f7d31425041c0c5198be..d370ec9cbd9075613f8ee589f2ba1665d12184e3 100644 (file)
@@ -11,9 +11,9 @@ def produce_test(parent, child, direction):
     """produce a testcase for A->B->C inheritance with a self-referential
     relationship between two of the classes, using either one-to-many or
     many-to-one.
-    
+
     the old "no discriminator column" pattern is used.
-    
+
     """
     class ABCTest(_base.MappedTest):
         @classmethod
index 0954349997ec3042cad2914268c47e71925b39bc..df7958b2ff2ae0d855f0ad6a4f903884c2f30e26 100644 (file)
@@ -84,7 +84,7 @@ class PolymorphicOnNotLocalTest(_base.MappedTest):
                 Column('id', Integer, primary_key=True), 
                 Column('y', String(10)), 
                 Column('xid', ForeignKey('t1.id')))
-    
+
     @testing.resolve_artifact_names
     def test_bad_polymorphic_on(self):
         class InterfaceBase(object):
@@ -126,8 +126,8 @@ class PolymorphicOnNotLocalTest(_base.MappedTest):
             "polymorphic loads will not function properly",
             go
         )
-        
-        
+
+
 class FalseDiscriminatorTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -135,7 +135,7 @@ class FalseDiscriminatorTest(_base.MappedTest):
         t1 = Table('t1', metadata, 
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True), 
             Column('type', Boolean, nullable=False))
-        
+
     def test_false_on_sub(self):
         class Foo(object):pass
         class Bar(Foo):pass
@@ -161,7 +161,7 @@ class FalseDiscriminatorTest(_base.MappedTest):
         assert d1.type is False
         sess.expunge_all()
         assert sess.query(Ding).one() is not None
-        
+
 class PolymorphicSynonymTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -175,7 +175,7 @@ class PolymorphicSynonymTest(_base.MappedTest):
                    Column('id', Integer, ForeignKey('t1.id'),
                                             primary_key=True),
                    Column('data', String(10), nullable=False))
-    
+
     def test_polymorphic_synonym(self):
         class T1(_fixtures.Base):
             def info(self):
@@ -183,9 +183,9 @@ class PolymorphicSynonymTest(_base.MappedTest):
             def _set_info(self, x):
                 self._info = x
             info = property(info, _set_info)
-            
+
         class T2(T1):pass
-        
+
         mapper(T1, t1, polymorphic_on=t1.c.type, polymorphic_identity='t1',
             properties={
                 'info':synonym('_info', map_column=True)
@@ -200,12 +200,12 @@ class PolymorphicSynonymTest(_base.MappedTest):
         sess.expunge_all()
         eq_(sess.query(T2).filter(T2.info=='at2').one(), at2)
         eq_(at2.info, "THE INFO IS:at2")
-        
+
 class PolymorphicAttributeManagementTest(_base.MappedTest):
     """Test polymorphic_on can be assigned, can be mirrored, etc."""
 
     run_setup_mappers = 'once'
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('table_a', metadata,
@@ -222,7 +222,7 @@ class PolymorphicAttributeManagementTest(_base.MappedTest):
            Column('id', Integer, ForeignKey('table_b.id'),
                                 primary_key=True)
         )
-    
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_classes(cls):
@@ -232,7 +232,7 @@ class PolymorphicAttributeManagementTest(_base.MappedTest):
             pass
         class C(B):
             pass
-        
+
         mapper(A, table_a, 
                         polymorphic_on=table_a.c.class_name, 
                         polymorphic_identity='a')
@@ -241,7 +241,7 @@ class PolymorphicAttributeManagementTest(_base.MappedTest):
                         polymorphic_identity='b')
         mapper(C, table_c, inherits=B, 
                         polymorphic_identity='c')
-    
+
     @testing.resolve_artifact_names
     def test_poly_configured_immediate(self):
         a = A()
@@ -250,7 +250,7 @@ class PolymorphicAttributeManagementTest(_base.MappedTest):
         eq_(a.class_name, 'a')
         eq_(b.class_name, 'b')
         eq_(c.class_name, 'c')
-        
+
     @testing.resolve_artifact_names
     def test_base_class(self):
         sess = Session()
@@ -273,7 +273,7 @@ class PolymorphicAttributeManagementTest(_base.MappedTest):
         sess.commit()
         sess.close()
         assert isinstance(sess.query(B).first(), C)
-    
+
 class CascadeTest(_base.MappedTest):
     """that cascades on polymorphic relationships continue
     cascading along the path of the instance's mapper, not
@@ -378,13 +378,13 @@ class M2OUseGetTest(_base.MappedTest):
             # the 'primaryjoin' looks just like "Sub"'s "get" clause (based on the Base id),
             # and foreign_keys since that join condition doesn't actually have any fks in it
             #'sub':relationship(Sub, primaryjoin=base.c.id==related.c.sub_id, foreign_keys=related.c.sub_id)
-            
+
             # now we can use this:
             'sub':relationship(Sub)
         })
-        
+
         assert class_mapper(Related).get_property('sub').strategy.use_get
-        
+
         sess = create_session()
         s1 = Sub()
         r1 = Related(sub=s1)
@@ -397,7 +397,7 @@ class M2OUseGetTest(_base.MappedTest):
         def go():
             assert r1.sub
         self.assert_sql_count(testing.db, go, 0)
-        
+
 
 class GetTest(_base.MappedTest):
     @classmethod
@@ -417,7 +417,7 @@ class GetTest(_base.MappedTest):
             Column('foo_id', Integer, ForeignKey('foo.id')),
             Column('bar_id', Integer, ForeignKey('bar.id')),
             Column('data', String(20)))
-    
+
     @classmethod
     def setup_classes(cls):
         class Foo(_base.BasicEntity):
@@ -431,7 +431,7 @@ class GetTest(_base.MappedTest):
 
     def test_get_polymorphic(self):
         self._do_get_test(True)
-    
+
     def test_get_nonpolymorphic(self):
         self._do_get_test(False)
 
@@ -469,7 +469,7 @@ class GetTest(_base.MappedTest):
                 assert sess.query(Blub).get(f.id) is None
                 assert sess.query(Blub).get(b.id) is None
                 assert sess.query(Bar).get(f.id) is None
-                
+
             self.assert_sql_count(testing.db, go, 0)
         else:
             # this is testing the 'wrong' behavior of using get()
@@ -498,7 +498,7 @@ class GetTest(_base.MappedTest):
 class EagerLazyTest(_base.MappedTest):
     """tests eager load/lazy load of child items off inheritance mappers, tests that
     LazyLoader constructs the right query condition."""
-    
+
     @classmethod
     def define_tables(cls, metadata):
         global foo, bar, bar_foo
@@ -544,7 +544,7 @@ class EagerLazyTest(_base.MappedTest):
 class EagerTargetingTest(_base.MappedTest):
     """test a scenario where joined table inheritance might be 
     confused as an eagerly loaded joined table."""
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('a_table', metadata,
@@ -558,14 +558,14 @@ class EagerTargetingTest(_base.MappedTest):
            Column('id', Integer, ForeignKey('a_table.id'), primary_key=True),
            Column('b_data', String(50)),
         )
-    
+
     @testing.resolve_artifact_names
     def test_adapt_stringency(self):
         class A(_base.ComparableEntity):
             pass
         class B(A):
             pass
-        
+
         mapper(A, a_table, polymorphic_on=a_table.c.type, polymorphic_identity='A', 
                 properties={
                     'children': relationship(A, order_by=a_table.c.name)
@@ -574,7 +574,7 @@ class EagerTargetingTest(_base.MappedTest):
         mapper(B, b_table, inherits=A, polymorphic_identity='B', properties={
                 'b_derived':column_property(b_table.c.b_data + "DATA")
                 })
-        
+
         sess=create_session()
 
         b1=B(id=1, name='b1',b_data='i')
@@ -591,15 +591,15 @@ class EagerTargetingTest(_base.MappedTest):
         node = sess.query(B).filter(B.id==bid).all()[0]
         eq_(node, B(id=1, name='b1',b_data='i'))
         eq_(node.children[0], B(id=2, name='b2',b_data='l'))
-        
+
         sess.expunge_all()
         node = sess.query(B).options(joinedload(B.children)).filter(B.id==bid).all()[0]
         eq_(node, B(id=1, name='b1',b_data='i'))
         eq_(node.children[0], B(id=2, name='b2',b_data='l'))
-        
+
 class FlushTest(_base.MappedTest):
     """test dependency sorting among inheriting mappers"""
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('users', metadata,
@@ -802,7 +802,7 @@ class VersioningTest(_base.MappedTest):
 class DistinctPKTest(_base.MappedTest):
     """test the construction of mapper.primary_key when an inheriting relationship
     joins on a column other than primary key column."""
-    
+
     run_inserts = 'once'
     run_deletes = None
 
@@ -886,7 +886,7 @@ class DistinctPKTest(_base.MappedTest):
 
 class SyncCompileTest(_base.MappedTest):
     """test that syncrules compile properly on custom inherit conds"""
-    
+
     @classmethod
     def define_tables(cls, metadata):
         global _a_table, _b_table, _c_table
@@ -955,17 +955,17 @@ class SyncCompileTest(_base.MappedTest):
 
 class OverrideColKeyTest(_base.MappedTest):
     """test overriding of column attributes."""
-    
+
     @classmethod
     def define_tables(cls, metadata):
         global base, subtable
-        
+
         base = Table('base', metadata, 
             Column('base_id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('data', String(255)),
             Column('sqlite_fixer', String(10))
             )
-            
+
         subtable = Table('subtable', metadata,
             Column('base_id', Integer, ForeignKey('base.base_id'), primary_key=True),
             Column('subdata', String(255))
@@ -980,7 +980,7 @@ class OverrideColKeyTest(_base.MappedTest):
 
         mapper(Base, base)
         mapper(Sub, subtable, inherits=Base)
-        
+
         # Sub gets a "base_id" property using the "base_id"
         # column of both tables.
         eq_(
@@ -992,12 +992,12 @@ class OverrideColKeyTest(_base.MappedTest):
         # this pattern is what you see when using declarative
         # in particular, here we do a "manual" version of
         # what we'd like the mapper to do.
-        
+
         class Base(object):
             pass
         class Sub(Base):
             pass
-        
+
         mapper(Base, base, properties={
             'id':base.c.base_id
         })
@@ -1018,7 +1018,7 @@ class OverrideColKeyTest(_base.MappedTest):
         sess.add(s1)
         sess.flush()
         assert sess.query(Sub).get(10) is s1
-    
+
     def test_override_onlyinparent(self):
         class Base(object):
             pass
@@ -1029,7 +1029,7 @@ class OverrideColKeyTest(_base.MappedTest):
             'id':base.c.base_id
         })
         mapper(Sub, subtable, inherits=Base)
-        
+
         eq_(
             class_mapper(Sub).get_property('id').columns,
             [base.c.base_id]
@@ -1039,28 +1039,28 @@ class OverrideColKeyTest(_base.MappedTest):
             class_mapper(Sub).get_property('base_id').columns,
             [subtable.c.base_id]
         )
-        
+
         s1 = Sub()
         s1.id = 10
-        
+
         s2 = Sub()
         s2.base_id = 15
-        
+
         sess = create_session()
         sess.add_all([s1, s2])
         sess.flush()
-        
+
         # s1 gets '10'
         assert sess.query(Sub).get(10) is s1
-        
+
         # s2 gets a new id, base_id is overwritten by the ultimate
         # PK col
         assert s2.id == s2.base_id != 15
-    
+
     def test_override_implicit(self):
         # this is originally [ticket:1111].
         # the pattern here is now disallowed by [ticket:1892]
-        
+
         class Base(object):
             pass
         class Sub(Base):
@@ -1069,7 +1069,7 @@ class OverrideColKeyTest(_base.MappedTest):
         mapper(Base, base, properties={
             'id':base.c.base_id
         })
-        
+
         def go():
             mapper(Sub, subtable, inherits=Base, properties={
                 'id':subtable.c.base_id
@@ -1082,7 +1082,7 @@ class OverrideColKeyTest(_base.MappedTest):
 
     def test_plain_descriptor(self):
         """test that descriptors prevent inheritance from propigating properties to subclasses."""
-        
+
         class Base(object):
             pass
         class Sub(Base):
@@ -1092,7 +1092,7 @@ class OverrideColKeyTest(_base.MappedTest):
 
         mapper(Base, base)
         mapper(Sub, subtable, inherits=Base)
-        
+
         s1 = Sub()
         sess = create_session()
         sess.add(s1)
@@ -1107,7 +1107,7 @@ class OverrideColKeyTest(_base.MappedTest):
                 if instance is None:
                     return self
                 return "im the data"
-            
+
         class Base(object):
             pass
         class Sub(Base):
@@ -1121,7 +1121,7 @@ class OverrideColKeyTest(_base.MappedTest):
         sess.add(s1)
         sess.flush()
         assert sess.query(Sub).one().data == "im the data"
-    
+
     def test_sub_columns_over_base_descriptors(self):
         class Base(object):
             @property
@@ -1133,7 +1133,7 @@ class OverrideColKeyTest(_base.MappedTest):
 
         mapper(Base, base)
         mapper(Sub, subtable, inherits=Base)
-        
+
         sess = create_session()
         b1 = Base()
         assert b1.subdata == "this is base"
@@ -1144,7 +1144,7 @@ class OverrideColKeyTest(_base.MappedTest):
         sess.add_all([s1, b1])
         sess.flush()
         sess.expunge_all()
-        
+
         assert sess.query(Base).get(b1.base_id).subdata == "this is base"
         assert sess.query(Sub).get(s1.base_id).subdata == "this is sub"
 
@@ -1175,7 +1175,7 @@ class OverrideColKeyTest(_base.MappedTest):
 
 class OptimizedLoadTest(_base.MappedTest):
     """tests for the "optimized load" routine."""
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('base', metadata,
@@ -1199,19 +1199,19 @@ class OptimizedLoadTest(_base.MappedTest):
             Column('a', String(10)),
             Column('b', String(10))
         )
-    
+
     @testing.resolve_artifact_names
     def test_optimized_passes(self):
         """"test that the 'optimized load' routine doesn't crash when 
         a column in the join condition is not available."""
-        
+
         class Base(_base.BasicEntity):
             pass
         class Sub(Base):
             pass
-            
+
         mapper(Base, base, polymorphic_on=base.c.type, polymorphic_identity='base')
-        
+
         # redefine Sub's "id" to favor the "id" col in the subtable.
         # "id" is also part of the primary join condition
         mapper(Sub, sub, inherits=Base, 
@@ -1222,7 +1222,7 @@ class OptimizedLoadTest(_base.MappedTest):
         sess.add(s1)
         sess.commit()
         sess.expunge_all()
-        
+
         # load s1 via Base.  s1.id won't populate since it's relative to 
         # the "sub" table.  The optimized load kicks in and tries to 
         # generate on the primary join, but cannot since "id" is itself unloaded.
@@ -1307,7 +1307,7 @@ class OptimizedLoadTest(_base.MappedTest):
         assert s2test.comp
         eq_(s1test.comp, Comp('ham', 'cheese'))
         eq_(s2test.comp, Comp('bacon', 'eggs'))
-    
+
     @testing.resolve_artifact_names
     def test_load_expired_on_pending(self):
         class Base(_base.ComparableEntity):
@@ -1343,7 +1343,7 @@ class OptimizedLoadTest(_base.MappedTest):
                 lambda ctx:{u'param_1': s1.id}
             ),
         )
-        
+
     @testing.resolve_artifact_names
     def test_dont_generate_on_none(self):
         class Base(_base.ComparableEntity):
@@ -1353,23 +1353,23 @@ class OptimizedLoadTest(_base.MappedTest):
         mapper(Base, base, polymorphic_on=base.c.type, 
                             polymorphic_identity='base')
         m = mapper(Sub, sub, inherits=Base, polymorphic_identity='sub')
-        
+
         s1 = Sub()
         assert m._optimized_get_statement(attributes.instance_state(s1), 
                                 ['counter2']) is None
-        
+
         # loads s1.id as None
         eq_(s1.id, None)
-        
+
         # this now will come up with a value of None for id - should reject
         assert m._optimized_get_statement(attributes.instance_state(s1), 
                                 ['counter2']) is None
-        
+
         s1.id = 1
         attributes.instance_state(s1).commit_all(s1.__dict__, None)
         assert m._optimized_get_statement(attributes.instance_state(s1), 
                                 ['counter2']) is not None
-        
+
     @testing.resolve_artifact_names
     def test_load_expired_on_pending_twolevel(self):
         class Base(_base.ComparableEntity):
@@ -1378,7 +1378,7 @@ class OptimizedLoadTest(_base.MappedTest):
             pass
         class SubSub(Sub):
             pass
-            
+
         mapper(Base, base, polymorphic_on=base.c.type, 
                     polymorphic_identity='base')
         mapper(Sub, sub, inherits=Base, polymorphic_identity='sub')
@@ -1419,7 +1419,7 @@ class OptimizedLoadTest(_base.MappedTest):
                 lambda ctx:{u'param_1': s1.id}
             ),
         )
-        
+
 class PKDiscriminatorTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -1427,7 +1427,7 @@ class PKDiscriminatorTest(_base.MappedTest):
                            Column('id', Integer, primary_key=True, 
                                     test_needs_autoincrement=True),
                            Column('name', String(60)))
-                           
+
         children = Table('children', metadata,
                         Column('id', Integer, ForeignKey('parents.id'), 
                                     primary_key=True),
@@ -1446,13 +1446,13 @@ class PKDiscriminatorTest(_base.MappedTest):
 
         class A(Child):
             pass
-            
+
         mapper(Parent, parents, properties={
             'children': relationship(Child, backref='parent'),
         })
         mapper(Child, children, polymorphic_on=children.c.type,
             polymorphic_identity=1)
-            
+
         mapper(A, inherits=Child, polymorphic_identity=2)
 
         s = create_session()
@@ -1464,26 +1464,26 @@ class PKDiscriminatorTest(_base.MappedTest):
 
         assert a.id
         assert a.type == 2
-        
+
         p.name='p1new'
         a.name='a1new'
         s.flush()
-        
+
         s.expire_all()
         assert a.name=='a1new'
         assert p.name=='p1new'
-        
-        
+
+
 class DeleteOrphanTest(_base.MappedTest):
     """Test the fairly obvious, that an error is raised
     when attempting to insert an orphan.
-    
+
     Previous SQLA versions would check this constraint 
     in memory which is the original rationale for this test.
-        
+
     """
-    
-    
+
+
     @classmethod
     def define_tables(cls, metadata):
         global single, parent
@@ -1493,31 +1493,31 @@ class DeleteOrphanTest(_base.MappedTest):
             Column('data', String(50)),
             Column('parent_id', Integer, ForeignKey('parent.id'), nullable=False),
             )
-            
+
         parent = Table('parent', metadata,
                 Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
                 Column('data', String(50))
             )
-    
+
     def test_orphan_message(self):
         class Base(_fixtures.Base):
             pass
-        
+
         class SubClass(Base):
             pass
-        
+
         class Parent(_fixtures.Base):
             pass
-        
+
         mapper(Base, single, polymorphic_on=single.c.type, polymorphic_identity='base')
         mapper(SubClass, inherits=Base, polymorphic_identity='sub')
         mapper(Parent, parent, properties={
             'related':relationship(Base, cascade="all, delete-orphan")
         })
-        
+
         sess = create_session()
         s1 = SubClass(data='s1')
         sess.add(s1)
         assert_raises(sa_exc.DBAPIError, sess.flush)
-        
-    
+
+
index 9db095d928c442f4fdd64b28f13d649cde94d509..4e20e7a78790a6718b1ec9343b610c227e93b091 100644 (file)
@@ -371,7 +371,7 @@ class ConcreteTest(_base.MappedTest):
 
         self.assert_sql_count(testing.db, go, 1)
 
-        
+
 class PropertyInheritanceTest(_base.MappedTest):
 
     @classmethod
@@ -389,7 +389,7 @@ class PropertyInheritanceTest(_base.MappedTest):
             primary_key=True, test_needs_autoincrement=True),
             Column('some_dest_id', Integer, ForeignKey('dest_table.id')),
             Column('cname', String(50)))
-            
+
         Table('dest_table', metadata, Column('id', Integer,
               primary_key=True, test_needs_autoincrement=True),
               Column('name', String(50)))
@@ -402,10 +402,10 @@ class PropertyInheritanceTest(_base.MappedTest):
 
         class B(A):
             pass
-        
+
         class C(A):
             pass
-            
+
         class Dest(_base.ComparableEntity):
             pass
 
@@ -418,14 +418,14 @@ class PropertyInheritanceTest(_base.MappedTest):
         dest = Dest()
         assert_raises(AttributeError, setattr, b, 'some_dest', dest)
         clear_mappers()
-        
+
         mapper(A, a_table, properties={'a_id': a_table.c.id})
         mapper(B, b_table, inherits=A, concrete=True)
         mapper(Dest, dest_table)
         b = B()
         assert_raises(AttributeError, setattr, b, 'a_id', 3)
         clear_mappers()
-        
+
         mapper(A, a_table, properties={'a_id': a_table.c.id})
         mapper(B, b_table, inherits=A, concrete=True)
         mapper(Dest, dest_table)
@@ -439,7 +439,7 @@ class PropertyInheritanceTest(_base.MappedTest):
                properties={
                     'some_dest': relationship(Dest, back_populates='many_b')
                 })
-                    
+
         mapper(Dest, dest_table, properties={
                     'many_a': relationship(A,back_populates='some_dest'), 
                     'many_b': relationship(B,back_populates='some_dest')
@@ -500,14 +500,14 @@ class PropertyInheritanceTest(_base.MappedTest):
             properties={
                     'some_dest': relationship(Dest, back_populates='many_a')},
             )
-            
+
         mapper(Dest, dest_table, properties={
                 'many_a': relationship(A,
                             back_populates='some_dest', 
                             order_by=ajoin.c.id)
                         }
                 )
-                
+
         sess = sessionmaker()()
         dest1 = Dest(name='c1')
         dest2 = Dest(name='c2')
@@ -517,12 +517,12 @@ class PropertyInheritanceTest(_base.MappedTest):
         b2 = B(some_dest=dest1, bname='b2', id=4)
         c1 = C(some_dest=dest1, cname='c1', id=5)
         c2 = C(some_dest=dest2, cname='c2', id=6)
-        
+
         eq_([a2, c2], dest2.many_a)
         eq_([a1, b1, b2, c1], dest1.many_a)
         sess.add_all([dest1, dest2])
         sess.commit()
-        
+
         assert sess.query(Dest).filter(Dest.many_a.contains(a2)).one() is dest2
         assert sess.query(Dest).filter(Dest.many_a.contains(b1)).one() is dest1
         assert sess.query(Dest).filter(Dest.many_a.contains(c2)).one() is dest2
@@ -576,7 +576,7 @@ class PropertyInheritanceTest(_base.MappedTest):
             properties={
                     'some_dest': relationship(Dest, back_populates='many_a')},
             )
-            
+
         mapper(Dest, dest_table, properties={
                 'many_a': relationship(A,
                             back_populates='some_dest', 
@@ -596,7 +596,7 @@ class PropertyInheritanceTest(_base.MappedTest):
         c1 = C(some_dest=dest2, cname='c1')
         sess.add_all([dest1, dest2, c1, a1, b1])
         sess.commit()
-        
+
         sess2 = sessionmaker()()
         merged_c1 = sess2.merge(c1)
         eq_(merged_c1.some_dest.name, 'd2')
index e38a1ec33abe99d252b2cfb248d0ab9b61e51ccd..868bbdcfc6b48a9a22ea03f981320a9cea3daf20 100644 (file)
@@ -198,7 +198,7 @@ def generate_round_trip_test(use_unions=False, use_joins=False):
         page3 = ClassifiedPage(magazine=magazine,page_no=3)
         session.add(pub)
 
-        
+
         session.flush()
         print [x for x in session]
         session.expunge_all()
index 7e31c476baaeae38bc3f1758f1b861de7873dc41..9cc58af9238c69852339962633ef12eb7037eb33 100644 (file)
@@ -123,7 +123,7 @@ def _generate_round_trip_test(include_base, lazy_relationship, redefine_colprop,
                         'engineer':people.join(engineers),
                         'manager':people.join(managers),
                     }, None, 'pjoin')
-                
+
             manager_join = people.join(managers).outerjoin(boss)
             person_with_polymorphic = ['*', person_join]
             manager_with_polymorphic = ['*', manager_join]
@@ -178,11 +178,11 @@ def _generate_round_trip_test(include_base, lazy_relationship, redefine_colprop,
             Engineer(status='CGG', engineer_name='engineer2', primary_language='python', **{person_attribute_name:'wally'}),
             Manager(status='ABA', manager_name='manager2', **{person_attribute_name:'jsmith'})
         ]
-        
+
         pointy = employees[0]
         jsmith = employees[-1]
         dilbert = employees[1]
-        
+
         session = create_session()
         c = Company(name='company1')
         c.employees = employees
@@ -190,7 +190,7 @@ def _generate_round_trip_test(include_base, lazy_relationship, redefine_colprop,
 
         session.flush()
         session.expunge_all()
-        
+
         eq_(session.query(Person).get(dilbert.person_id), dilbert)
         session.expunge_all()
 
@@ -200,7 +200,7 @@ def _generate_round_trip_test(include_base, lazy_relationship, redefine_colprop,
         def go():
             cc = session.query(Company).get(c.company_id)
             eq_(cc.employees, employees)
-            
+
         if not lazy_relationship:
             if with_polymorphic != 'none':
                 self.assert_sql_count(testing.db, go, 1)
@@ -212,7 +212,7 @@ def _generate_round_trip_test(include_base, lazy_relationship, redefine_colprop,
                 self.assert_sql_count(testing.db, go, 2)
             else:
                 self.assert_sql_count(testing.db, go, 6)
-        
+
         # test selecting from the query, using the base mapped table (people) as the selection criterion.
         # in the case of the polymorphic Person query, the "people" selectable should be adapted to be "person_join"
         eq_(
@@ -226,7 +226,7 @@ def _generate_round_trip_test(include_base, lazy_relationship, redefine_colprop,
             session.query(Engineer).filter(getattr(Person, person_attribute_name)=='dilbert').first(),
             dilbert
         )
-        
+
         # test selecting from the query, joining against an alias of the base "people" table.  test that
         # the "palias" alias does *not* get sucked up into the "person_join" conversion.
         palias = people.alias("palias")
@@ -235,12 +235,12 @@ def _generate_round_trip_test(include_base, lazy_relationship, redefine_colprop,
         assert dilbert is session.query(Engineer).filter((palias.c.name=='dilbert') & (palias.c.person_id==Person.person_id)).first()
         assert dilbert is session.query(Person).filter((Engineer.engineer_name=="engineer1") & (engineers.c.person_id==people.c.person_id)).first()
         assert dilbert is session.query(Engineer).filter(Engineer.engineer_name=="engineer1")[0]
-        
+
         dilbert.engineer_name = 'hes dibert!'
 
         session.flush()
         session.expunge_all()
-        
+
         def go():
             session.query(Person).filter(getattr(Person, person_attribute_name)=='dilbert').first()
         self.assert_sql_count(testing.db, go, 1)
@@ -255,7 +255,7 @@ def _generate_round_trip_test(include_base, lazy_relationship, redefine_colprop,
         daboss = Boss(status='BBB', manager_name='boss', golf_swing='fore', **{person_attribute_name:'daboss'})
         session.add(daboss)
         assert_raises(sa_exc.DBAPIError, session.flush)
-        
+
         c = session.query(Company).first()
         daboss.company = c
         manager_list = [e for e in c.employees if isinstance(e, Manager)]
@@ -264,12 +264,12 @@ def _generate_round_trip_test(include_base, lazy_relationship, redefine_colprop,
 
         eq_(session.query(Manager).order_by(Manager.person_id).all(), manager_list)
         c = session.query(Company).first()
-        
+
         session.delete(c)
         session.flush()
-        
+
         eq_(people.count().scalar(), 0)
-        
+
     test_roundtrip = function_named(
         test_roundtrip, "test_%s%s%s_%s" % (
           (lazy_relationship and "lazy" or "eager"),
index 2a9341692d9c44868d263c52f5fd4b4ded73f01a..92af79ae13f05e0628502b4b7a496e9c5527f761 100644 (file)
@@ -47,9 +47,9 @@ class RelationshipTest1(_base.MappedTest):
             pass
         class Manager(Person):
             pass
-        
+
         # note that up until recently (0.4.4), we had to specify "foreign_keys" here
-        # for this primary join.  
+        # for this primary join.
         mapper(Person, people, properties={
             'manager':relationship(Manager, primaryjoin=(people.c.manager_id ==
                                                      managers.c.person_id),
@@ -57,9 +57,9 @@ class RelationshipTest1(_base.MappedTest):
         })
         mapper(Manager, managers, inherits=Person,
                inherit_condition=people.c.person_id==managers.c.person_id)
-        
+
         eq_(class_mapper(Person).get_property('manager').synchronize_pairs, [(managers.c.person_id,people.c.manager_id)])
-        
+
         session = create_session()
         p = Person(name='some person')
         m = Manager(name='some manager')
@@ -382,7 +382,7 @@ class RelationshipTest4(_base.MappedTest):
         session.flush()
 
         session.expunge_all()
-    
+
         def go():
             testcar = session.query(Car).options(joinedload('employee')).get(car1.car_id)
             assert str(testcar.employee) == "Engineer E4, status X"
@@ -661,13 +661,13 @@ class RelationshipTest8(_base.MappedTest):
         sess = create_session()
         sess.add(t1)
         sess.flush()
-        
+
         sess.expunge_all()
         eq_(
             sess.query(Taggable).order_by(Taggable.id).all(),
             [User(data='u1'), Taggable(owner=User(data='u1'))]
         )
-        
+
 class GenerativeTest(TestBase, AssertsExecutionResults):
     @classmethod
     def setup_class(cls):
@@ -787,7 +787,7 @@ class GenerativeTest(TestBase, AssertsExecutionResults):
         # added here for testing
         e = exists([Car.owner], Car.owner==employee_join.c.person_id)
         Query(Person)._adapt_clause(employee_join, False, False)
-        
+
         r = session.query(Person).filter(Person.name.like('%2')).join('status').filter_by(name="active").order_by(Person.person_id)
         eq_(str(list(r)), "[Manager M2, category YYYYYYYYY, status Status active, Engineer E2, field X, status Status active]")
         r = session.query(Engineer).join('status').filter(Person.name.in_(['E2', 'E3', 'E4', 'M4', 'M2', 'M1']) & (status.c.name=="active")).order_by(Person.name)
@@ -1092,7 +1092,7 @@ class MissingPolymorphicOnTest(_base.MappedTest):
             Column('id', Integer, ForeignKey('tablec.id'), primary_key=True),
             Column('ddata', String(50)),
             )
-            
+
     def test_polyon_col_setsup(self):
         class A(_fixtures.Base):
             pass
@@ -1102,16 +1102,16 @@ class MissingPolymorphicOnTest(_base.MappedTest):
             pass
         class D(C):
             pass
-            
+
         poly_select = select([tablea, tableb.c.data.label('discriminator')], from_obj=tablea.join(tableb)).alias('poly')
-        
+
         mapper(B, tableb)
         mapper(A, tablea, with_polymorphic=('*', poly_select), polymorphic_on=poly_select.c.discriminator, properties={
             'b':relationship(B, uselist=False)
         })
         mapper(C, tablec, inherits=A,polymorphic_identity='c')
         mapper(D, tabled, inherits=C, polymorphic_identity='d')
-        
+
         c = C(cdata='c1', adata='a1', b=B(data='c'))
         d = D(cdata='c2', adata='a2', ddata='d2', b=B(data='d'))
         sess = create_session()
@@ -1120,4 +1120,4 @@ class MissingPolymorphicOnTest(_base.MappedTest):
         sess.flush()
         sess.expunge_all()
         eq_(sess.query(A).all(), [C(cdata='c1', adata='a1'), D(cdata='c2', adata='a2', ddata='d2')])
-        
+
index 36a23204d82d8c08e18a0541837983dcbba61c10..61727eb4e107dcf305d44f65a853a514438b610c 100644 (file)
@@ -25,7 +25,7 @@ class Boss(Manager):
 
 class Machine(_fixtures.Base):
     pass
-    
+
 class Paperwork(_fixtures.Base):
     pass
 
@@ -34,7 +34,7 @@ def _produce_test(select_type):
         run_inserts = 'once'
         run_setup_mappers = 'once'
         run_deletes = None
-        
+
         @classmethod
         def define_tables(cls, metadata):
             global companies, people, engineers, managers, boss, paperwork, machines
@@ -55,12 +55,12 @@ def _produce_test(select_type):
                Column('engineer_name', String(50)),
                Column('primary_language', String(50)),
               )
-         
+
             machines = Table('machines', metadata,
                 Column('machine_id', Integer, primary_key=True, test_needs_autoincrement=True),
                 Column('name', String(50)),
                 Column('engineer_id', Integer, ForeignKey('engineers.person_id')))
-            
+
             managers = Table('managers', metadata,
                Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
                Column('status', String(30)),
@@ -78,7 +78,7 @@ def _produce_test(select_type):
                 Column('person_id', Integer, ForeignKey('people.person_id')))
 
             clear_mappers()
-            
+
             mapper(Company, companies, properties={
                 'employees':relationship(Person, order_by=people.c.person_id)
             })
@@ -129,7 +129,7 @@ def _produce_test(select_type):
                         inherits=Person, polymorphic_identity='manager')
             mapper(Boss, boss, inherits=Manager, polymorphic_identity='boss')
             mapper(Paperwork, paperwork)
-        
+
 
         @classmethod
         def insert_data(cls):
@@ -165,7 +165,7 @@ def _produce_test(select_type):
                     Machine(name="Commodore 64"),
                     Machine(name="IBM 3270")
             ])
-        
+
             c2.employees = [e3]
             sess = create_session()
             sess.add(c1)
@@ -176,10 +176,10 @@ def _produce_test(select_type):
             all_employees = [e1, e2, b1, m1, e3]
             c1_employees = [e1, e2, b1, m1]
             c2_employees = [e3]
-        
+
         def test_loads_at_once(self):
             """test that all objects load from the full query, when with_polymorphic is used"""
-            
+
             sess = create_session()
             def go():
                 eq_(sess.query(Person).all(), all_employees)
@@ -187,7 +187,7 @@ def _produce_test(select_type):
 
         def test_foo(self):
             sess = create_session()
-            
+
             def go():
                 eq_(sess.query(Person).options(subqueryload(Engineer.machines)).all(), all_employees)
             self.assert_sql_count(testing.db, go, {'':14, 'Unions':8, 'Polymorphic':7}.get(select_type, 8))
@@ -197,13 +197,13 @@ def _produce_test(select_type):
 
             # for both joinedload() and subqueryload(), if the original q is not loading
             # the subclass table, the joinedload doesn't happen.
-            
+
             def go():
                 eq_(sess.query(Person).options(joinedload(Engineer.machines))[1:3], all_employees[1:3])
             self.assert_sql_count(testing.db, go, {'':6, 'Polymorphic':3}.get(select_type, 4))
 
             sess = create_session()
-            
+
             def go():
                 eq_(sess.query(Person).options(subqueryload(Engineer.machines)).all(), all_employees)
             self.assert_sql_count(testing.db, go, {'':14, 'Unions':8, 'Polymorphic':7}.get(select_type, 8))
@@ -220,26 +220,26 @@ def _produce_test(select_type):
                         options(joinedload(Engineer.machines))[1:3], 
                     all_employees[1:3])
             self.assert_sql_count(testing.db, go, 3)
-            
-            
+
+
         def test_get(self):
             sess = create_session()
-            
+
             # for all mappers, ensure the primary key has been calculated as just the "person_id"
             # column
             eq_(sess.query(Person).get(e1.person_id), Engineer(name="dilbert", primary_language="java"))
             eq_(sess.query(Engineer).get(e1.person_id), Engineer(name="dilbert", primary_language="java"))
             eq_(sess.query(Manager).get(b1.person_id), Boss(name="pointy haired boss", golf_swing="fore"))
-        
+
         def test_multi_join(self):
             sess = create_session()
 
             e = aliased(Person)
             c = aliased(Company)
-            
+
             q = sess.query(Company, Person, c, e).join(Person, Company.employees).join(e, c.employees).\
                     filter(Person.name=='dilbert').filter(e.name=='wally')
-            
+
             eq_(q.count(), 1)
             eq_(q.all(), [
                 (
@@ -249,7 +249,7 @@ def _produce_test(select_type):
                     Engineer(status=u'regular engineer',engineer_name=u'wally',name=u'wally',company_id=1,primary_language=u'c++',person_id=2,type=u'engineer')
                 )
             ])
-            
+
         def test_filter_on_subclass(self):
             sess = create_session()
             eq_(sess.query(Engineer).all()[0], Engineer(name="dilbert"))
@@ -261,7 +261,7 @@ def _produce_test(select_type):
             eq_(sess.query(Manager).filter(Manager.person_id==m1.person_id).one(), Manager(name="dogbert"))
 
             eq_(sess.query(Manager).filter(Manager.person_id==b1.person_id).one(), Boss(name="pointy haired boss"))
-        
+
             eq_(sess.query(Boss).filter(Boss.person_id==b1.person_id).one(), Boss(name="pointy haired boss"))
 
         def test_join_from_polymorphic(self):
@@ -288,7 +288,7 @@ def _produce_test(select_type):
 
                 sess.expunge_all()
                 eq_(sess.query(Person).with_polymorphic([Manager, Engineer]).join('paperwork', aliased=aliased).filter(Person.name.like('%dog%')).filter(Paperwork.description.like('%#2%')).all(), [m1])
-    
+
         def test_join_to_polymorphic(self):
             sess = create_session()
             eq_(sess.query(Company).join('employees').filter(Person.name=='vlad').one(), c2)
@@ -302,7 +302,7 @@ def _produce_test(select_type):
                 sess.query(Company).\
                     filter(Company.employees.any(Person.name=='vlad')).all(), [c2]
             )
-            
+
             # test that the aliasing on "Person" does not bleed into the
             # EXISTS clause generated by any()
             eq_(
@@ -314,12 +314,12 @@ def _produce_test(select_type):
                 sess.query(Company).join(Company.employees, aliased=True).filter(Person.name=='dilbert').\
                     filter(Company.employees.any(Person.name=='vlad')).all(), []
             )
-            
+
             eq_(
                 sess.query(Company).filter(Company.employees.of_type(Engineer).any(Engineer.primary_language=='cobol')).one(),
                 c2
                 )
-            
+
             calias = aliased(Company)
             eq_(
                 sess.query(calias).filter(calias.employees.of_type(Engineer).any(Engineer.primary_language=='cobol')).one(),
@@ -343,12 +343,12 @@ def _produce_test(select_type):
             eq_(
                 sess.query(Person).filter(Person.paperwork.any(Paperwork.description=="review #2")).all(), [m1]
             )
-            
+
             eq_(
                 sess.query(Company).filter(Company.employees.of_type(Engineer).any(and_(Engineer.primary_language=='cobol'))).one(),
                 c2
                 )
-        
+
         def test_join_from_columns_or_subclass(self):
             sess = create_session()
 
@@ -356,7 +356,7 @@ def _produce_test(select_type):
                 sess.query(Manager.name).order_by(Manager.name).all(),
                 [(u'dogbert',), (u'pointy haired boss',)]
             )
-            
+
             eq_(
                 sess.query(Manager.name).join(Paperwork, Manager.paperwork).order_by(Manager.name).all(),
                 [(u'dogbert',), (u'dogbert',), (u'pointy haired boss',)]
@@ -366,20 +366,20 @@ def _produce_test(select_type):
                 sess.query(Person.name).join(Paperwork, Person.paperwork).order_by(Person.name).all(),
                 [(u'dilbert',), (u'dilbert',), (u'dogbert',), (u'dogbert',), (u'pointy haired boss',), (u'vlad',), (u'wally',), (u'wally',)]
             )
-            
+
             # Load Person.name, joining from Person -> paperwork, get all
             # the people.
             eq_(
                 sess.query(Person.name).join(paperwork, Person.person_id==paperwork.c.person_id).order_by(Person.name).all(),
                 [(u'dilbert',), (u'dilbert',), (u'dogbert',), (u'dogbert',), (u'pointy haired boss',), (u'vlad',), (u'wally',), (u'wally',)]
             )
-            
+
             # same, on manager.  get only managers.
             eq_(
                 sess.query(Manager.name).join(paperwork, Manager.person_id==paperwork.c.person_id).order_by(Person.name).all(),
                 [(u'dogbert',), (u'dogbert',), (u'pointy haired boss',)]
             )
-            
+
             if select_type == '':
                 # this now raises, due to [ticket:1892].  Manager.person_id is now the "person_id" column on Manager.
                 # the SQL is incorrect.
@@ -400,8 +400,8 @@ def _produce_test(select_type):
                     sess.query(Person.name).join(paperwork, Manager.person_id==paperwork.c.person_id).order_by(Person.name).all(),
                     [(u'dogbert',), (u'dogbert',), (u'pointy haired boss',)]
                 )
-                    
-                
+
+
             eq_(
                 sess.query(Manager).join(Paperwork, Manager.paperwork).order_by(Manager.name).all(),
                 [m1, b1]
@@ -416,7 +416,7 @@ def _produce_test(select_type):
                 sess.query(Manager.person_id).join(paperwork, Manager.person_id==paperwork.c.person_id).order_by(Manager.name).all(),
                 [(4,), (4,), (3,)]
             )
-            
+
             eq_(
                 sess.query(Manager.name, Paperwork.description).
                     join(Paperwork, Manager.person_id==Paperwork.person_id).
@@ -424,41 +424,41 @@ def _produce_test(select_type):
                     all(),
                 [(u'pointy haired boss', u'review #1'), (u'dogbert', u'review #2'), (u'dogbert', u'review #3')]
             )
-            
+
             malias = aliased(Manager)
             eq_(
                 sess.query(malias.name).join(paperwork, malias.person_id==paperwork.c.person_id).all(),
                 [(u'pointy haired boss',), (u'dogbert',), (u'dogbert',)]
             )
-        
+
         def test_polymorphic_option(self):
             """test that polymorphic loading sets state.load_path with its actual mapper
             on a subclass, and not the superclass mapper.
-            
+
             """
             paths = []
             class MyOption(interfaces.MapperOption):
                 propagate_to_loaders = True
                 def process_query_conditionally(self, query):
                     paths.append(query._current_path)
-            
+
             sess = create_session()
             dilbert, boss = sess.query(Person).\
                             options(MyOption()).\
                             filter(Person.name.in_(['dilbert', 'pointy haired boss'])).\
                             order_by(Person.name).\
                             all()
-                            
+
             dilbert.machines
             boss.paperwork
             eq_(paths, 
                 [(class_mapper(Engineer), 'machines'), 
                 (class_mapper(Boss), 'paperwork')])
-            
-            
+
+
         def test_expire(self):
             """test that individual column refresh doesn't get tripped up by the select_table mapper"""
-            
+
             sess = create_session()
             m1 = sess.query(Manager).filter(Manager.name=='dogbert').one()
             sess.expire(m1)
@@ -467,16 +467,16 @@ def _produce_test(select_type):
             m2 = sess.query(Manager).filter(Manager.name=='pointy haired boss').one()
             sess.expire(m2, ['manager_name', 'golf_swing'])
             assert m2.golf_swing=='fore'
-            
+
         def test_with_polymorphic(self):
-            
+
             sess = create_session()
-            
-            
+
+
             assert_raises(sa_exc.InvalidRequestError, sess.query(Person).with_polymorphic, Paperwork)
             assert_raises(sa_exc.InvalidRequestError, sess.query(Engineer).with_polymorphic, Boss)
             assert_raises(sa_exc.InvalidRequestError, sess.query(Engineer).with_polymorphic, Person)
-            
+
             # compare to entities without related collections to prevent additional lazy SQL from firing on 
             # loaded entities
             emps_without_relationships = [
@@ -487,12 +487,12 @@ def _produce_test(select_type):
                 Engineer(name="vlad", engineer_name="vlad", primary_language="cobol", status="elbonian engineer")
             ]
             eq_(sess.query(Person).with_polymorphic('*').all(), emps_without_relationships)
-            
-            
+
+
             def go():
                 eq_(sess.query(Person).with_polymorphic(Engineer).filter(Engineer.primary_language=='java').all(), emps_without_relationships[0:1])
             self.assert_sql_count(testing.db, go, 1)
-            
+
             sess.expunge_all()
             def go():
                 eq_(sess.query(Person).with_polymorphic('*').all(), emps_without_relationships)
@@ -507,13 +507,13 @@ def _produce_test(select_type):
             def go():
                 eq_(sess.query(Person).with_polymorphic(Engineer, people.outerjoin(engineers)).all(), emps_without_relationships)
             self.assert_sql_count(testing.db, go, 3)
-            
+
             sess.expunge_all()
             def go():
                 # limit the polymorphic join down to just "Person", overriding select_table
                 eq_(sess.query(Person).with_polymorphic(Person).all(), emps_without_relationships)
             self.assert_sql_count(testing.db, go, 6)
-        
+
         def test_relationship_to_polymorphic(self):
             assert_result = [
                 Company(name="MegaCorp, Inc.", employees=[
@@ -528,14 +528,14 @@ def _produce_test(select_type):
                     Engineer(name="vlad", engineer_name="vlad", primary_language="cobol", status="elbonian engineer")
                 ])
             ]
-            
+
             sess = create_session()
-            
+
             def go():
                 # test load Companies with lazy load to 'employees'
                 eq_(sess.query(Company).all(), assert_result)
             self.assert_sql_count(testing.db, go, {'':9, 'Polymorphic':4}.get(select_type, 5))
-        
+
             sess = create_session()
             def go():
                 # currently, it doesn't matter if we say Company.employees, 
@@ -546,14 +546,14 @@ def _produce_test(select_type):
                                         joinedload_all(Company.employees.of_type(Engineer), Engineer.machines
                                     )).all(), 
                         assert_result)
-            
+
             # in the case of select_type='', the joinedload 
             # doesn't take in this case; it joinedloads company->people, 
-            # then a load for each of 5 rows, then lazyload of "machines"            
+            # then a load for each of 5 rows, then lazyload of "machines"
             self.assert_sql_count(testing.db, go, 
                                     {'':7, 'Polymorphic':1}.get(select_type, 2)
                                     )
-            
+
             sess = create_session()
             def go():
                 eq_(
@@ -561,7 +561,7 @@ def _produce_test(select_type):
                                     subqueryload_all(Company.employees.of_type(Engineer), Engineer.machines
                                 )).all(), 
                             assert_result)
-        
+
             self.assert_sql_count(
                             testing.db, go, 
                             {'':8, 
@@ -570,7 +570,7 @@ def _produce_test(select_type):
                                 'Polymorphic':3,
                                 'AliasedJoins':4}[select_type]
                         )
-    
+
         def test_joinedload_on_subclass(self):
             sess = create_session()
             def go():
@@ -588,7 +588,7 @@ def _produce_test(select_type):
                 )
             self.assert_sql_count(testing.db, go, 2)
 
-            
+
         def test_query_subclass_join_to_base_relationship(self):
             sess = create_session()
             # non-polymorphic
@@ -601,7 +601,7 @@ def _produce_test(select_type):
             if select_type == '':
                 eq_(sess.query(Company).select_from(companies.join(people).join(engineers)).filter(Engineer.primary_language=='java').all(), [c1])
                 eq_(sess.query(Company).join(people.join(engineers), 'employees').filter(Engineer.primary_language=='java').all(), [c1])
-                
+
                 ealias = aliased(Engineer)
                 eq_(sess.query(Company).join(ealias, 'employees').filter(ealias.primary_language=='java').all(), [c1])
 
@@ -616,7 +616,7 @@ def _produce_test(select_type):
                 eq_(sess.query(Person).join(Engineer.machines).filter(Machine.name.ilike("%ibm%")).all(), [e1, e3])
                 eq_(sess.query(Company).join('employees', Engineer.machines).all(), [c1, c2])
                 eq_(sess.query(Company).join('employees', Engineer.machines).filter(Machine.name.ilike("%thinkpad%")).all(), [c1])
-            
+
             # non-polymorphic
             eq_(sess.query(Engineer).join(Engineer.machines).all(), [e1, e2, e3])
             eq_(sess.query(Engineer).join(Engineer.machines).filter(Machine.name.ilike("%ibm%")).all(), [e1, e3])
@@ -647,7 +647,7 @@ def _produce_test(select_type):
                         join('employees', 'paperwork', aliased=aliased).filter(Person.name.in_(['dilbert', 'vlad'])).filter(Paperwork.description.like('%#2%')).all(),
                     [c1]
                 )
-        
+
                 eq_(
                     sess.query(Company).\
                         join('employees', 'paperwork', aliased=aliased).filter(Person.name.in_(['dilbert', 'vlad'])).filter(Paperwork.description.like('%#%')).all(),
@@ -686,31 +686,31 @@ def _produce_test(select_type):
                     filter(Engineer.engineer_name=='vlad').one(),
                 c2
             )
-                
-        
+
+
         def test_filter_on_baseclass(self):
             sess = create_session()
 
             eq_(sess.query(Person).all(), all_employees)
 
             eq_(sess.query(Person).first(), all_employees[0])
-        
+
             eq_(sess.query(Person).filter(Person.person_id==e2.person_id).one(), e2)
-    
+
         def test_from_alias(self):
             sess = create_session()
-            
+
             palias = aliased(Person)
             eq_(
                 sess.query(palias).filter(palias.name.in_(['dilbert', 'wally'])).all(),
                 [e1, e2]
             )
-            
+
         def test_self_referential(self):
             sess = create_session()
-            
+
             c1_employees = [e1, e2, b1, m1]
-            
+
             palias = aliased(Person)
             eq_(
                 sess.query(Person, palias).filter(Person.company_id==palias.company_id).filter(Person.name=='dogbert').\
@@ -731,17 +731,17 @@ def _produce_test(select_type):
                     (m1, b1),
                 ]
             )
-        
+
         def test_nesting_queries(self):
             sess = create_session()
-            
+
             # query.statement places a flag "no_adapt" on the returned statement.  This prevents
             # the polymorphic adaptation in the second "filter" from hitting it, which would pollute 
             # the subquery and usually results in recursion overflow errors within the adaption.
             subq = sess.query(engineers.c.person_id).filter(Engineer.primary_language=='java').statement.as_scalar()
-            
+
             eq_(sess.query(Person).filter(Person.person_id==subq).one(), e1)
-            
+
         def test_mixed_entities(self):
             sess = create_session()
 
@@ -756,8 +756,8 @@ def _produce_test(select_type):
                 [(Engineer(status=u'elbonian engineer',engineer_name=u'vlad',name=u'vlad',primary_language=u'cobol'),
                     u'Elbonia, Inc.')]
             )
-            
-            
+
+
             eq_(
                 sess.query(Manager.name).all(), 
                 [('pointy haired boss', ), ('dogbert',)]
@@ -771,7 +771,7 @@ def _produce_test(select_type):
             row = sess.query(Engineer.name, Engineer.primary_language).filter(Engineer.name=='dilbert').first()
             assert row.name == 'dilbert'
             assert row.primary_language == 'java'
-            
+
 
             eq_(
                 sess.query(Engineer.name, Engineer.primary_language).all(),
@@ -782,7 +782,7 @@ def _produce_test(select_type):
                 sess.query(Boss.name, Boss.golf_swing).all(),
                 [(u'pointy haired boss', u'fore')]
             )
-            
+
             # TODO: I think raise error on these for now.  different inheritance/loading schemes have different
             # results here, all incorrect
             #
@@ -790,7 +790,7 @@ def _produce_test(select_type):
             #    sess.query(Person.name, Engineer.primary_language).all(),
             #    []
             # )
-            
+
             # self.assertEquals(
             #    sess.query(Person.name, Engineer.primary_language, Manager.manager_name).all(),
             #    []
@@ -815,7 +815,7 @@ def _produce_test(select_type):
                     (Engineer(status=u'elbonian engineer',engineer_name=u'vlad',name=u'vlad',company_id=2,primary_language=u'cobol',person_id=5,type=u'engineer'), u'Elbonia, Inc.')
                     ]
                 )
-            
+
                 eq_(
                     sess.query(Engineer.primary_language, Company.name).join(Company.employees).filter(Person.type=='engineer').order_by(desc(Engineer.primary_language)).all(),
                     [(u'java', u'MegaCorp, Inc.'), (u'cobol', u'Elbonia, Inc.'), (u'c++', u'MegaCorp, Inc.')]
@@ -841,7 +841,7 @@ def _produce_test(select_type):
                 sess.query(Person.name, Company.name, palias.name).join(Company.employees).filter(Company.name=='Elbonia, Inc.').filter(palias.name=='dilbert').all(),
                 [(u'vlad', u'Elbonia, Inc.', u'dilbert')]
             )
-            
+
             palias = aliased(Person)
             eq_(
                 sess.query(Person.type, Person.name, palias.type, palias.name).filter(Person.company_id==palias.company_id).filter(Person.name=='dogbert').\
@@ -850,7 +850,7 @@ def _produce_test(select_type):
                 (u'manager', u'dogbert', u'engineer', u'wally'), 
                 (u'manager', u'dogbert', u'boss', u'pointy haired boss')]
             )
-        
+
             eq_(
                 sess.query(Person.name, Paperwork.description).filter(Person.person_id==Paperwork.person_id).order_by(Person.name, Paperwork.description).all(), 
                 [(u'dilbert', u'tps report #1'), (u'dilbert', u'tps report #2'), (u'dogbert', u'review #2'), 
@@ -867,7 +867,7 @@ def _produce_test(select_type):
                     sess.query(func.count(Person.person_id)).filter(Engineer.primary_language=='java').all(), 
                     [(1, )]
                 )
-            
+
             eq_(
                 sess.query(Company.name, func.count(Person.person_id)).filter(Company.company_id==Person.company_id).group_by(Company.name).order_by(Company.name).all(),
                 [(u'Elbonia, Inc.', 1), (u'MegaCorp, Inc.', 4)]
@@ -877,20 +877,20 @@ def _produce_test(select_type):
                 sess.query(Company.name, func.count(Person.person_id)).join(Company.employees).group_by(Company.name).order_by(Company.name).all(),
                 [(u'Elbonia, Inc.', 1), (u'MegaCorp, Inc.', 4)]
             )
-    
-    
+
+
     PolymorphicQueryTest.__name__ = "Polymorphic%sTest" % select_type
     return PolymorphicQueryTest
 
 for select_type in ('', 'Polymorphic', 'Unions', 'AliasedJoins', 'Joins'):
     testclass = _produce_test(select_type)
     exec("%s = testclass" % testclass.__name__)
-    
+
 del testclass
 
 class SelfReferentialTestJoinedToBase(_base.MappedTest):
     run_setup_mappers = 'once'
-    
+
     @classmethod
     def define_tables(cls, metadata):
         global people, engineers
@@ -913,9 +913,9 @@ class SelfReferentialTestJoinedToBase(_base.MappedTest):
           polymorphic_identity='engineer', properties={
           'reports_to':relationship(Person, primaryjoin=people.c.person_id==engineers.c.reports_to_id)
         })
-    
+
     def test_has(self):
-        
+
         p1 = Person(name='dogbert')
         e1 = Engineer(name='dilbert', primary_language='java', reports_to=p1)
         sess = create_session()
@@ -923,7 +923,7 @@ class SelfReferentialTestJoinedToBase(_base.MappedTest):
         sess.add(e1)
         sess.flush()
         sess.expunge_all()
-        
+
         eq_(sess.query(Engineer).filter(Engineer.reports_to.has(Person.name=='dogbert')).first(), Engineer(name='dilbert'))
 
     def test_oftype_aliases_in_exists(self):
@@ -932,9 +932,9 @@ class SelfReferentialTestJoinedToBase(_base.MappedTest):
         sess = create_session()
         sess.add_all([e1, e2])
         sess.flush()
-        
+
         eq_(sess.query(Engineer).filter(Engineer.reports_to.of_type(Engineer).has(Engineer.name=='dilbert')).first(), e2)
-        
+
     def test_join(self):
         p1 = Person(name='dogbert')
         e1 = Engineer(name='dilbert', primary_language='java', reports_to=p1)
@@ -943,7 +943,7 @@ class SelfReferentialTestJoinedToBase(_base.MappedTest):
         sess.add(e1)
         sess.flush()
         sess.expunge_all()
-        
+
         eq_(
             sess.query(Engineer).join('reports_to', aliased=True).filter(Person.name=='dogbert').first(), 
             Engineer(name='dilbert'))
@@ -964,7 +964,7 @@ class SelfReferentialJ2JTest(_base.MappedTest):
            Column('primary_language', String(50)),
            Column('reports_to_id', Integer, ForeignKey('managers.person_id'))
           )
-          
+
         managers = Table('managers', metadata,
             Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
         )
@@ -973,7 +973,7 @@ class SelfReferentialJ2JTest(_base.MappedTest):
     def setup_mappers(cls):
         mapper(Person, people, polymorphic_on=people.c.type, polymorphic_identity='person')
         mapper(Manager, managers, inherits=Person, polymorphic_identity='manager')
-        
+
         mapper(Engineer, engineers, inherits=Person, 
           polymorphic_identity='engineer', properties={
           'reports_to':relationship(Manager, primaryjoin=managers.c.person_id==engineers.c.reports_to_id, backref='engineers')
@@ -1003,7 +1003,7 @@ class SelfReferentialJ2JTest(_base.MappedTest):
         eq_(
             sess.query(Engineer).join('reports_to', aliased=True).filter(Manager.name=='dogbert').first(), 
             Engineer(name='dilbert'))
-    
+
     def test_filter_aliasing(self):
         m1 = Manager(name='dogbert')
         m2 = Manager(name='foo')
@@ -1033,7 +1033,7 @@ class SelfReferentialJ2JTest(_base.MappedTest):
                 (m1, e1),
             ]
         )
-        
+
     def test_relationship_compare(self):
         m1 = Manager(name='dogbert')
         m2 = Manager(name='foo')
@@ -1059,17 +1059,17 @@ class SelfReferentialJ2JTest(_base.MappedTest):
             [m1]
         )
 
-        
+
 
 class M2MFilterTest(_base.MappedTest):
     run_setup_mappers = 'once'
     run_inserts = 'once'
     run_deletes = None
-    
+
     @classmethod
     def define_tables(cls, metadata):
         global people, engineers, organizations, engineers_to_org
-        
+
         organizations = Table('organizations', metadata,
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('name', String(50)),
@@ -1078,7 +1078,7 @@ class M2MFilterTest(_base.MappedTest):
             Column('org_id', Integer, ForeignKey('organizations.id')),
             Column('engineer_id', Integer, ForeignKey('engineers.person_id')),
         )
-        
+
         people = Table('people', metadata,
            Column('person_id', Integer, primary_key=True, test_needs_autoincrement=True),
            Column('name', String(50)),
@@ -1094,14 +1094,14 @@ class M2MFilterTest(_base.MappedTest):
         global Organization
         class Organization(_fixtures.Base):
             pass
-            
+
         mapper(Organization, organizations, properties={
             'engineers':relationship(Engineer, secondary=engineers_to_org, backref='organizations')
         })
-        
+
         mapper(Person, people, polymorphic_on=people.c.type, polymorphic_identity='person')
         mapper(Engineer, engineers, inherits=Person, polymorphic_identity='engineer')
-    
+
     @classmethod
     def insert_data(cls):
         e1 = Engineer(name='e1')
@@ -1110,23 +1110,23 @@ class M2MFilterTest(_base.MappedTest):
         e4 = Engineer(name='e4')
         org1 = Organization(name='org1', engineers=[e1, e2])
         org2 = Organization(name='org2', engineers=[e3, e4])
-        
+
         sess = create_session()
         sess.add(org1)
         sess.add(org2)
         sess.flush()
-        
+
     def test_not_contains(self):
         sess = create_session()
-        
+
         e1 = sess.query(Person).filter(Engineer.name=='e1').one()
-        
+
         # this works
         eq_(sess.query(Organization).filter(~Organization.engineers.of_type(Engineer).contains(e1)).all(), [Organization(name='org2')])
 
         # this had a bug
         eq_(sess.query(Organization).filter(~Organization.engineers.contains(e1)).all(), [Organization(name='org2')])
-    
+
     def test_any(self):
         sess = create_session()
         eq_(sess.query(Organization).filter(Organization.engineers.of_type(Engineer).any(Engineer.name=='e1')).all(), [Organization(name='org1')])
@@ -1134,7 +1134,7 @@ class M2MFilterTest(_base.MappedTest):
 
 class SelfReferentialM2MTest(_base.MappedTest, AssertsCompiledSQL):
     run_setup_mappers = 'once'
-    
+
     @classmethod
     def define_tables(cls, metadata):
         global Parent, Child1, Child2
@@ -1167,19 +1167,19 @@ class SelfReferentialM2MTest(_base.MappedTest, AssertsCompiledSQL):
                uselist = False, backref="right_children"
                                )
 
-    
+
     def test_query_crit(self):
         session = create_session()
         c11, c12, c13 = Child1(), Child1(), Child1()
         c21, c22, c23 = Child2(), Child2(), Child2()
-        
+
         c11.left_child2 = c22
         c12.left_child2 = c22
         c13.left_child2 = c23
-        
+
         session.add_all([c11, c12, c13, c21, c22, c23])
         session.flush()
-        
+
         # test that the join to Child2 doesn't alias Child1 in the select
         eq_(
             set(session.query(Child1).join(Child1.left_child2)), 
@@ -1210,12 +1210,12 @@ class SelfReferentialM2MTest(_base.MappedTest, AssertsCompiledSQL):
 
     def test_eager_join(self):
         session = create_session()
-        
+
         c1 = Child1()
         c1.left_child2 = Child2()
         session.add(c1)
         session.flush()
-        
+
         q = session.query(Child1).options(joinedload('left_child2'))
 
         # test that the splicing of the join works here, doesnt break in the middle of "parent join child1"
@@ -1233,21 +1233,21 @@ class SelfReferentialM2MTest(_base.MappedTest, AssertsCompiledSQL):
 
         # another way to check
         assert q.limit(1).with_labels().subquery().count().scalar() == 1
-        
+
         assert q.first() is c1
-    
+
     def test_subquery_load(self):
         session = create_session()
-        
+
         c1 = Child1()
         c1.left_child2 = Child2()
         session.add(c1)
         session.flush()
         session.expunge_all()
-        
+
         for row in session.query(Child1).options(subqueryload('left_child2')).all():
             assert row.left_child2
-        
+
 class EagerToSubclassTest(_base.MappedTest):
     """Test joinedloads to subclass mappers"""
 
index a65851a5fc96f57ed9faed661b05ef10919e7781..b5b9dbf884a76a2a1f1bde5fafbf0483489308fb 100644 (file)
@@ -43,7 +43,7 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, MappedTest):
         mapper(Manager, inherits=Employee, polymorphic_identity='manager')
         mapper(Engineer, inherits=Employee, polymorphic_identity='engineer')
         mapper(JuniorEngineer, inherits=Engineer, polymorphic_identity='juniorengineer')
-        
+
     @testing.resolve_artifact_names
     def test_single_inheritance(self):
 
@@ -59,7 +59,7 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, MappedTest):
         assert session.query(Engineer).all() == [e1, e2]
         assert session.query(Manager).all() == [m1]
         assert session.query(JuniorEngineer).all() == [e2]
-        
+
         m1 = session.query(Manager).one()
         session.expire(m1, ['manager_data'])
         eq_(m1.manager_data, "knows how to manage things")
@@ -71,11 +71,11 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, MappedTest):
     @testing.resolve_artifact_names
     def test_multi_qualification(self):
         session = create_session()
-        
+
         m1 = Manager(name='Tom', manager_data='knows how to manage things')
         e1 = Engineer(name='Kurt', engineer_info='knows how to hack')
         e2 = JuniorEngineer(name='Ed', engineer_info='oh that ed')
-        
+
         session.add_all([m1, e1, e2])
         session.flush()
 
@@ -84,7 +84,7 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, MappedTest):
             session.query(Manager, ealias).all(), 
             [(m1, e1), (m1, e2)]
         )
-    
+
         eq_(
             session.query(Manager.name).all(),
             [("Tom",)]
@@ -104,12 +104,12 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, MappedTest):
             session.query(Manager).add_entity(ealias).all(),
             [(m1, e1), (m1, e2)]
         )
-        
+
         eq_(
             session.query(Manager.name).add_column(ealias.name).all(),
             [("Tom", "Kurt"), ("Tom", "Ed")]
         )
-        
+
         # TODO: I think raise error on this for now
         # self.assertEquals(
         #    session.query(Employee.name, Manager.manager_data, Engineer.engineer_info).all(), 
@@ -140,7 +140,7 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, MappedTest):
                             'anon_1 WHERE anon_1.employees_type IN '
                             '(:type_1, :type_2)',
                             use_default_dialect=True)
-        
+
     @testing.resolve_artifact_names
     def test_select_from(self):
         sess = create_session()
@@ -150,12 +150,12 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, MappedTest):
         e2 = JuniorEngineer(name='Ed', engineer_info='oh that ed')
         sess.add_all([m1, m2, e1, e2])
         sess.flush()
-        
+
         eq_(
             sess.query(Manager).select_from(employees.select().limit(10)).all(), 
             [m1, m2]
         )
-        
+
     @testing.resolve_artifact_names
     def test_count(self):
         sess = create_session()
@@ -169,7 +169,7 @@ class SingleInheritanceTest(testing.AssertsCompiledSQL, MappedTest):
         eq_(sess.query(Manager).count(), 2)
         eq_(sess.query(Engineer).count(), 2)
         eq_(sess.query(Employee).count(), 4)
-        
+
         eq_(sess.query(Manager).filter(Manager.name.like('%m%')).count(), 2)
         eq_(sess.query(Employee).filter(Employee.name.like('%m%')).count(), 3)
 
@@ -216,13 +216,13 @@ class RelationshipFromSingleTest(testing.AssertsCompiledSQL, MappedTest):
             Column('name', String(50)),
             Column('type', String(20)),
         )
-        
+
         Table('employee_stuff', metadata,
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('employee_id', Integer, ForeignKey('employee.id')),
             Column('name', String(50)),
         )
-    
+
     @classmethod
     def setup_classes(cls):
         class Employee(ComparableEntity):
@@ -239,7 +239,7 @@ class RelationshipFromSingleTest(testing.AssertsCompiledSQL, MappedTest):
             'stuff':relationship(Stuff)
         })
         mapper(Stuff, employee_stuff)
-        
+
         sess = create_session()
         context = sess.query(Manager).options(subqueryload('stuff'))._compile_context()
         subq = context.attributes[('subquery', (class_mapper(Employee), 'stuff'))]
@@ -270,17 +270,17 @@ class RelationshipToSingleTest(MappedTest):
             Column('type', String(20)),
             Column('company_id', Integer, ForeignKey('companies.company_id'))
         )
-        
+
         Table('companies', metadata,
             Column('company_id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('name', String(50)),
         )
-    
+
     @classmethod
     def setup_classes(cls):
         class Company(ComparableEntity):
             pass
-            
+
         class Employee(ComparableEntity):
             pass
         class Manager(Employee):
@@ -300,10 +300,10 @@ class RelationshipToSingleTest(MappedTest):
         mapper(Engineer, inherits=Employee, polymorphic_identity='engineer')
         mapper(JuniorEngineer, inherits=Engineer, polymorphic_identity='juniorengineer')
         sess = sessionmaker()()
-        
+
         c1 = Company(name='c1')
         c2 = Company(name='c2')
-        
+
         m1 = Manager(name='Tom', manager_data='data1', company=c1)
         m2 = Manager(name='Tom2', manager_data='data2', company=c2)
         e1 = Engineer(name='Kurt', engineer_info='knows how to hack', company=c2)
@@ -338,10 +338,10 @@ class RelationshipToSingleTest(MappedTest):
         mapper(Engineer, inherits=Employee, polymorphic_identity='engineer')
         mapper(JuniorEngineer, inherits=Engineer, polymorphic_identity='juniorengineer')
         sess = sessionmaker()()
-        
+
         c1 = Company(name='c1')
         c2 = Company(name='c2')
-        
+
         m1 = Manager(name='Tom', manager_data='data1', company=c1)
         m2 = Manager(name='Tom2', manager_data='data2', company=c2)
         e1 = Engineer(name='Kurt', engineer_info='knows how to hack', company=c2)
@@ -351,7 +351,7 @@ class RelationshipToSingleTest(MappedTest):
 
         eq_(c1.engineers, [e2])
         eq_(c2.engineers, [e1])
-        
+
         sess.expunge_all()
         eq_(sess.query(Company).order_by(Company.name).all(), 
             [
@@ -377,7 +377,7 @@ class RelationshipToSingleTest(MappedTest):
                 (Company(name='c2'), Engineer(name='Kurt'))
             ]
         )
-        
+
         # join() to Company.engineers, Engineer as the requested entity.
         # this actually applies the IN criterion twice which is less than ideal.
         sess.expunge_all()
@@ -396,7 +396,7 @@ class RelationshipToSingleTest(MappedTest):
             ]
         )
 
-        # this however fails as it does not limit the subtypes to just "Engineer".  
+        # this however fails as it does not limit the subtypes to just "Engineer".
         # with joins constructed by filter(), we seem to be following a policy where
         # we don't try to make decisions on how to join to the target class, whereas when using join() we
         # seem to have a lot more capabilities.
@@ -412,12 +412,12 @@ class RelationshipToSingleTest(MappedTest):
                 ]
             )
         go()
-        
+
 class SingleOnJoinedTest(MappedTest):
     @classmethod
     def define_tables(cls, metadata):
         global persons_table, employees_table
-        
+
         persons_table = Table('persons', metadata,
            Column('person_id', Integer, primary_key=True, test_needs_autoincrement=True),
            Column('name', String(50)),
@@ -429,7 +429,7 @@ class SingleOnJoinedTest(MappedTest):
            Column('employee_data', String(50)),
            Column('manager_data', String(50)),
         )
-    
+
     def test_single_on_joined(self):
         class Person(_fixtures.Base):
             pass
@@ -437,18 +437,18 @@ class SingleOnJoinedTest(MappedTest):
             pass
         class Manager(Employee):
             pass
-        
+
         mapper(Person, persons_table, polymorphic_on=persons_table.c.type, polymorphic_identity='person')
         mapper(Employee, employees_table, inherits=Person,polymorphic_identity='engineer')
         mapper(Manager, inherits=Employee,polymorphic_identity='manager')
-        
+
         sess = create_session()
         sess.add(Person(name='p1'))
         sess.add(Employee(name='e1', employee_data='ed1'))
         sess.add(Manager(name='m1', employee_data='ed2', manager_data='md1'))
         sess.flush()
         sess.expunge_all()
-        
+
         eq_(sess.query(Person).order_by(Person.person_id).all(), [
             Person(name='p1'),
             Employee(name='e1', employee_data='ed1'),
@@ -466,7 +466,7 @@ class SingleOnJoinedTest(MappedTest):
             Manager(name='m1', employee_data='ed2', manager_data='md1')
         ])
         sess.expunge_all()
-        
+
         def go():
             eq_(sess.query(Person).with_polymorphic('*').order_by(Person.person_id).all(), [
                 Person(name='p1'),
@@ -474,4 +474,4 @@ class SingleOnJoinedTest(MappedTest):
                 Manager(name='m1', employee_data='ed2', manager_data='md1')
             ])
         self.assert_sql_count(testing.db, go, 1)
-    
+
index cedf027ddb9139a8a840b773ebce7ea26fb72efc..eb4104355d1f4ad8e018939db5ffb51a9adf0262 100644 (file)
@@ -21,15 +21,15 @@ class EagerTest(_base.MappedTest):
     run_deletes = None
     run_inserts = "once"
     run_setup_mappers = "once"
-    
+
     @classmethod
     def define_tables(cls, metadata):
-        
+
         if testing.db.dialect.supports_native_boolean:
             false = 'false'
         else:
             false = "0"
-            
+
         cls.other_artifacts['false'] = false
 
         Table('owners', metadata ,
@@ -338,7 +338,7 @@ class EagerTest3(_base.MappedTest):
         arb_result = [row['data_id'] for row in arb_result]
 
         arb_data = arb_data.alias('arb')
-        
+
         # now query for Data objects using that above select, adding the
         # "order by max desc" separately
         q = (session.query(Data).
index e82e9e854b3bf9711370fd6623aa12f3d8592d74..5d74c2062791cd79d71fec23b3e8e9c78dae6b04 100644 (file)
@@ -122,13 +122,13 @@ class AttributesTest(_base.ORMTest):
         self.assert_(len(o4.mt2) == 1)
         self.assert_(o4.mt2[0].a == 'abcde')
         self.assert_(o4.mt2[0].b is None)
-    
+
     def test_state_gc(self):
         """test that InstanceState always has a dict, even after host object gc'ed."""
-        
+
         class Foo(object):
             pass
-        
+
         instrumentation.register_class(Foo)
         f = Foo()
         state = attributes.instance_state(f)
@@ -138,7 +138,7 @@ class AttributesTest(_base.ORMTest):
         gc_collect()
         assert state.obj() is None
         assert state.dict == {}
-        
+
     def test_deferred(self):
         class Foo(object):pass
 
@@ -233,24 +233,24 @@ class AttributesTest(_base.ORMTest):
         a.email_address = 'foo@bar.com'
         u.addresses.append(a)
         self.assert_(u.user_id == 7 and u.user_name == 'heythere' and u.addresses[0].email_address == 'lala@123.com' and u.addresses[1].email_address == 'foo@bar.com')
-    
+
     def test_extension_commit_attr(self):
         """test that an extension which commits attribute history
         maintains the end-result history.
-        
+
         This won't work in conjunction with some unitofwork extensions.
-        
+
         """
-        
+
         class Foo(_base.ComparableEntity):
             pass
         class Bar(_base.ComparableEntity):
             pass
-        
+
         class ReceiveEvents(AttributeExtension):
             def __init__(self, key):
                 self.key = key
-                
+
             def append(self, state, child, initiator):
                 if commit:
                     state.commit_all(state.dict)
@@ -270,34 +270,34 @@ class AttributesTest(_base.ORMTest):
         instrumentation.register_class(Bar)
 
         b1, b2, b3, b4 = Bar(id='b1'), Bar(id='b2'), Bar(id='b3'), Bar(id='b4')
-        
+
         def loadcollection(state, passive):
             if passive is attributes.PASSIVE_NO_FETCH:
                 return attributes.PASSIVE_NO_RESULT
             return [b1, b2]
-        
+
         def loadscalar(state, passive):
             if passive is attributes.PASSIVE_NO_FETCH:
                 return attributes.PASSIVE_NO_RESULT
             return b2
-            
+
         attributes.register_attribute(Foo, 'bars', 
                                uselist=True, 
                                useobject=True, 
                                callable_=loadcollection,
                                extension=[ReceiveEvents('bars')])
-                               
+
         attributes.register_attribute(Foo, 'bar', 
                               uselist=False, 
                               useobject=True, 
                               callable_=loadscalar,
                               extension=[ReceiveEvents('bar')])
-                              
+
         attributes.register_attribute(Foo, 'scalar', 
                             uselist=False, 
                             useobject=False, extension=[ReceiveEvents('scalar')])
-        
-            
+
+
         def create_hist():
             def hist(key, shouldmatch, fn, *arg):
                 attributes.instance_state(f1).commit_all(attributes.instance_dict(f1))
@@ -314,7 +314,7 @@ class AttributesTest(_base.ORMTest):
             hist('scalar', True, setattr, f1, 'scalar', 5)
             hist('scalar', True, setattr, f1, 'scalar', None)
             hist('scalar', True, setattr, f1, 'scalar', 4)
-        
+
         histories = []
         commit = False
         create_hist()
@@ -330,7 +330,7 @@ class AttributesTest(_base.ORMTest):
                 eq_(woc, wic)
             else:
                 ne_(woc, wic)
-        
+
     def test_extension_lazyload_assertion(self):
         class Foo(_base.BasicEntity):
             pass
@@ -356,7 +356,7 @@ class AttributesTest(_base.ORMTest):
         def func1(state, passive):
             if passive is attributes.PASSIVE_NO_FETCH:
                 return attributes.PASSIVE_NO_RESULT
-            
+
             return [bar1, bar2, bar3]
 
         attributes.register_attribute(Foo, 'bars', uselist=True,
@@ -367,20 +367,20 @@ class AttributesTest(_base.ORMTest):
 
         x = Foo()
         assert_raises(AssertionError, Bar(id=4).foos.append, x)
-        
+
         x.bars
         b = Bar(id=4)
         b.foos.append(x)
         attributes.instance_state(x).expire_attributes(attributes.instance_dict(x), ['bars'])
         assert_raises(AssertionError, b.foos.remove, x)
-        
-        
+
+
     def test_scalar_listener(self):
         # listeners on ScalarAttributeImpl and MutableScalarAttributeImpl aren't used normally.
         # test that they work for the benefit of user extensions
         class Foo(object):
             pass
-        
+
         results = []
         class ReceiveEvents(AttributeExtension):
             def append(self, state, child, initiator):
@@ -392,11 +392,11 @@ class AttributesTest(_base.ORMTest):
             def set(self, state, child, oldchild, initiator):
                 results.append(("set", state.obj(), child, oldchild))
                 return child
-        
+
         instrumentation.register_class(Foo)
         attributes.register_attribute(Foo, 'x', uselist=False, mutable_scalars=False, useobject=False, extension=ReceiveEvents())
         attributes.register_attribute(Foo, 'y', uselist=False, mutable_scalars=True, useobject=False, copy_function=lambda x:x, extension=ReceiveEvents())
-        
+
         f = Foo()
         f.x = 5
         f.x = 17
@@ -404,7 +404,7 @@ class AttributesTest(_base.ORMTest):
         f.y = [1,2,3]
         f.y = [4,5,6]
         del f.y
-        
+
         eq_(results, [
             ('set', f, 5, None),
             ('set', f, 17, 5),
@@ -413,12 +413,12 @@ class AttributesTest(_base.ORMTest):
             ('set', f, [4,5,6], [1,2,3]),
             ('remove', f, [4,5,6])
         ])
-        
-        
+
+
     def test_lazytrackparent(self):
         """test that the "hasparent" flag works properly 
            when lazy loaders and backrefs are used
-           
+
         """
 
         class Post(object):pass
@@ -640,7 +640,7 @@ class AttributesTest(_base.ORMTest):
 
         attributes.unregister_attribute(Foo, "collection")
         assert not attributes.manager_of_class(Foo).is_instrumented("collection")
-        
+
         try:
             attributes.register_attribute(Foo, "collection", uselist=True, typecallable=dict, useobject=True)
             assert False
@@ -690,11 +690,11 @@ class UtilTest(_base.ORMTest):
 
         class Bar(object):
             pass
-        
+
         instrumentation.register_class(Foo)
         instrumentation.register_class(Bar)
         attributes.register_attribute(Foo, "coll", uselist=True, useobject=True)
-    
+
         f1 = Foo()
         b1 = Bar()
         b2 = Bar()
@@ -706,7 +706,7 @@ class UtilTest(_base.ORMTest):
         eq_(attributes.get_history(f1, "coll"), ([b1], [], []))
         attributes.set_committed_value(f1, "coll", [b2])
         eq_(attributes.get_history(f1, "coll"), ((), [b2], ()))
-        
+
         attributes.del_attribute(f1, "coll")
         assert "coll" not in f1.__dict__
 
@@ -781,11 +781,11 @@ class BackrefTest(_base.ORMTest):
 
         attributes.register_attribute(Port, 'jack', uselist=False, 
                                             useobject=True, backref="port")
-        
+
         attributes.register_attribute(Jack, 'port', uselist=False,
                                             useobject=True, backref="jack")
-        
-                
+
+
         p = Port()
         j = Jack()
         p.jack = j
@@ -800,7 +800,7 @@ class BackrefTest(_base.ORMTest):
         a token that is global to all InstrumentedAttribute objects
         within a particular class, not just the indvidual IA object
         since we use distinct objects in an inheritance scenario.
-        
+
         """
         class Parent(object):
             pass
@@ -811,7 +811,7 @@ class BackrefTest(_base.ORMTest):
 
         p_token = object()
         c_token = object()
-        
+
         instrumentation.register_class(Parent)
         instrumentation.register_class(Child)
         instrumentation.register_class(SubChild)
@@ -828,11 +828,11 @@ class BackrefTest(_base.ORMTest):
                 backref="child",
                 parent_token = c_token,
                 useobject=True)
-        
+
         p1 = Parent()
         c1 = Child()
         p1.child = c1
-        
+
         c2 = SubChild()
         c2.parent = p1
 
@@ -846,7 +846,7 @@ class BackrefTest(_base.ORMTest):
 
         p_token = object()
         c_token = object()
-        
+
         instrumentation.register_class(Parent)
         instrumentation.register_class(SubParent)
         instrumentation.register_class(Child)
@@ -862,26 +862,26 @@ class BackrefTest(_base.ORMTest):
                 backref='children',
                 parent_token = c_token,
                 useobject=True)
-        
+
         p1 = Parent()
         p2 = SubParent()
         c1 = Child()
-        
+
         p1.children.append(c1)
 
         assert c1.parent is p1
         assert c1 in p1.children
-        
+
         p2.children.append(c1)
         assert c1.parent is p2
-        
+
         # note its still in p1.children -
         # the event model currently allows only
         # one level deep.  without the parent_token,
         # it keeps going until a ValueError is raised
         # and this condition changes.
         assert c1 in p1.children
-        
+
 class PendingBackrefTest(_base.ORMTest):
     def setup(self):
         global Post, Blog, called, lazy_load
@@ -926,7 +926,7 @@ class PendingBackrefTest(_base.ORMTest):
 
         b = Blog("blog 1")
         p = Post("post 4")
-        
+
         p.blog = b
         p = Post("post 5")
         p.blog = b
@@ -936,17 +936,17 @@ class PendingBackrefTest(_base.ORMTest):
         # calling backref calls the callable, populates extra posts
         assert b.posts == [p1, p2, p3, Post("post 4"), Post("post 5")]
         assert called[0] == 1
-    
+
     def test_lazy_history(self):
         global lazy_load
 
         p1, p2, p3 = Post("post 1"), Post("post 2"), Post("post 3")
         lazy_load = [p1, p2, p3]
-        
+
         b = Blog("blog 1")
         p = Post("post 4")
         p.blog = b
-        
+
         p4 = Post("post 5")
         p4.blog = b
         assert called[0] == 0
@@ -1022,7 +1022,7 @@ class HistoryTest(_base.ORMTest):
         f = Foo()
         f.someattr = 3
         eq_(Foo.someattr.impl.get_committed_value(attributes.instance_state(f), attributes.instance_dict(f)), None)
-        
+
         attributes.instance_state(f).commit(attributes.instance_dict(f), ['someattr'])
         eq_(Foo.someattr.impl.get_committed_value(attributes.instance_state(f), attributes.instance_dict(f)), 3)
 
@@ -1084,8 +1084,8 @@ class HistoryTest(_base.ORMTest):
         eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), (['one'], (), ()))
         f.someattr = 'two'
         eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), (['two'], (), ()))
-        
-        
+
+
     def test_mutable_scalar(self):
         class Foo(_base.BasicEntity):
             pass
@@ -1138,12 +1138,12 @@ class HistoryTest(_base.ORMTest):
 
         attributes.instance_state(f).commit_all(attributes.instance_dict(f))
         eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ((), [{'a':'b'},], ()))
-        
+
         f.someattr['a'] = 'c'
         eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ((), [{'a':'c'},], ()))
         attributes.flag_modified(f, 'someattr')
         eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ([{'a':'c'},], (), ()))
-        
+
         f.someattr = ['a']
         eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ([['a']], (), ()))
         attributes.instance_state(f).commit_all(attributes.instance_dict(f))
@@ -1156,7 +1156,7 @@ class HistoryTest(_base.ORMTest):
         attributes.flag_modified(f, 'someattr')
 
         eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ([['b', 'c']], (), ()))
-        
+
     def test_use_object(self):
         class Foo(_base.BasicEntity):
             pass
@@ -1395,10 +1395,10 @@ class HistoryTest(_base.ORMTest):
 
         attributes.instance_state(f).commit_all(attributes.instance_dict(f))
         eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ((), [hi, there, hi], ()))
-        
+
         f.someattr = []
         eq_(attributes.get_state_history(attributes.instance_state(f), 'someattr'), ([], [], [hi, there, hi]))
-        
+
     def test_collections_via_backref(self):
         class Foo(_base.BasicEntity):
             pass
@@ -1621,12 +1621,12 @@ class HistoryTest(_base.ORMTest):
 class ListenerTest(_base.ORMTest):
     def test_receive_changes(self):
         """test that Listeners can mutate the given value."""
-        
+
         class Foo(object):
             pass
         class Bar(object):
             pass
-            
+
         def append(state, child, initiator):
             b2 = Bar()
             b2.data = b1.data + " appended"
@@ -1641,11 +1641,11 @@ class ListenerTest(_base.ORMTest):
         attributes.register_attribute(Foo, 'barlist', uselist=True, useobject=True)
         attributes.register_attribute(Foo, 'barset', typecallable=set, uselist=True, useobject=True)
         attributes.register_attribute(Bar, 'data', uselist=False, useobject=False)
-        
+
         event.listen(Foo.data, 'set', on_set, retval=True)
         event.listen(Foo.barlist, 'append', append, retval=True)
         event.listen(Foo.barset, 'append', append, retval=True)
-        
+
         f1 = Foo()
         f1.data = "some data"
         eq_(f1.data, "some data modified")
@@ -1654,10 +1654,10 @@ class ListenerTest(_base.ORMTest):
         f1.barlist.append(b1)
         assert b1.data == "some bar"
         assert f1.barlist[0].data == "some bar appended"
-        
+
         f1.barset.add(b1)
         assert f1.barset.pop().data == "some bar appended"
-    
+
     def test_propagate(self):
         classes = [None, None, None]
         canary = []
@@ -1665,45 +1665,45 @@ class ListenerTest(_base.ORMTest):
             class A(object):
                 pass
             classes[0] = A
-            
+
         def make_b():
             class B(classes[0]):
                 pass
             classes[1] = B
-        
+
         def make_c():
             class C(classes[1]):
                 pass
             classes[2] = C
-            
+
         def instrument_a():
             instrumentation.register_class(classes[0])
 
         def instrument_b():
             instrumentation.register_class(classes[1])
-        
+
         def instrument_c():
             instrumentation.register_class(classes[2])
-            
+
         def attr_a():
             attributes.register_attribute(classes[0], 'attrib', uselist=False, useobject=False)
-        
+
         def attr_b():
             attributes.register_attribute(classes[1], 'attrib', uselist=False, useobject=False)
 
         def attr_c():
             attributes.register_attribute(classes[2], 'attrib', uselist=False, useobject=False)
-        
+
         def set(state, value, oldvalue, initiator):
             canary.append(value)
-            
+
         def events_a():
             event.listen(classes[0].attrib, 'set', set, propagate=True)
-        
+
         def teardown():
             classes[:] = [None, None, None]
             canary[:] = []
-        
+
         ordering = [
             (instrument_a, instrument_b),
             (instrument_b, instrument_c),
@@ -1722,20 +1722,20 @@ class ListenerTest(_base.ORMTest):
         elements = [make_a, make_b, make_c, 
                     instrument_a, instrument_b, instrument_c, 
                     attr_a, attr_b, attr_c, events_a]
-        
+
         for i, series in enumerate(all_partial_orderings(ordering, elements)):
             for fn in series:
                 fn()
-                
+
             b = classes[1]()
             b.attrib = "foo"
             eq_(b.attrib, "foo")
             eq_(canary, ["foo"])
-            
+
             c = classes[2]()
             c.attrib = "bar"
             eq_(c.attrib, "bar")
             eq_(canary, ["foo", "bar"])
-            
+
             teardown()
-        
+
index 455e93a30c3595745d7b97e2460ff08f41932710..d0aae128c4037ca136bc181cac5c685e7ccbb1d5 100644 (file)
@@ -40,15 +40,15 @@ class O2MCollectionTest(_fixtures.FixtureTest):
         u2= User(name='ed')
         sess.add_all([u1, a1, a2, a3])
         sess.commit()
-        
+
         #u1.addresses
-        
+
         def go():
             u2.addresses.append(a1)
             u2.addresses.append(a2)
             u2.addresses.append(a3)
         self.assert_sql_count(testing.db, go, 0)
-        
+
     @testing.resolve_artifact_names
     def test_collection_move_preloaded(self):
         sess = sessionmaker()()
@@ -87,7 +87,7 @@ class O2MCollectionTest(_fixtures.FixtureTest):
 
         # backref fires
         assert a1.user is u2
-        
+
         # u1.addresses wasn't loaded,
         # so when it loads its correct
         assert a1 not in u1.addresses
@@ -110,7 +110,7 @@ class O2MCollectionTest(_fixtures.FixtureTest):
 
         # backref fires
         assert a1.user is u2
-        
+
         # everything expires, no changes in 
         # u1.addresses, so all is fine
         sess.commit()
@@ -144,7 +144,7 @@ class O2MCollectionTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_plain_load_passive(self):
         """test that many-to-one set doesn't load the old value."""
-        
+
         sess = sessionmaker()()
         u1 = User(name='jack')
         u2 = User(name='ed')
@@ -159,10 +159,10 @@ class O2MCollectionTest(_fixtures.FixtureTest):
         def go():
             a1.user = u2
         self.assert_sql_count(testing.db, go, 0)
-        
+
         assert a1 not in u1.addresses
         assert a1 in u2.addresses
-        
+
     @testing.resolve_artifact_names
     def test_set_none(self):
         sess = sessionmaker()()
@@ -176,11 +176,11 @@ class O2MCollectionTest(_fixtures.FixtureTest):
         def go():
             a1.user = None
         self.assert_sql_count(testing.db, go, 0)
-        
+
         assert a1 not in u1.addresses
-        
-        
-        
+
+
+
     @testing.resolve_artifact_names
     def test_scalar_move_notloaded(self):
         sess = sessionmaker()()
@@ -218,7 +218,7 @@ class O2MCollectionTest(_fixtures.FixtureTest):
         # "old" u1 here allows the backref
         # to remove it from the addresses collection
         a1.user = u2
-        
+
         sess.commit()
         assert a1 not in u1.addresses
         assert a1 in u2.addresses
@@ -271,13 +271,13 @@ class O2OScalarBackrefMoveTest(_fixtures.FixtureTest):
 
         # load a1.user
         a1.user
-        
+
         # reassign
         a2.user = u1
 
         # backref fires
         assert u1.address is a2
-        
+
         # stays on both sides
         assert a1.user is u1
         assert a2.user is u1
@@ -298,7 +298,7 @@ class O2OScalarBackrefMoveTest(_fixtures.FixtureTest):
 
         # backref fires
         assert a1.user is u2
-        
+
         # u1.address loads now after a flush
         assert u1.address is None
         assert u2.address is a1
@@ -361,7 +361,7 @@ class O2OScalarBackrefMoveTest(_fixtures.FixtureTest):
 
         # load
         assert a1.user is u1
-        
+
         # reassign
         a2.user = u1
 
@@ -370,7 +370,7 @@ class O2OScalarBackrefMoveTest(_fixtures.FixtureTest):
 
         # didnt work this way tho
         assert a1.user is u1
-        
+
         # moves appropriately after commit
         sess.commit()
         assert u1.address is a2
@@ -429,19 +429,19 @@ class O2OScalarOrphanTest(_fixtures.FixtureTest):
         sess = sessionmaker()()
         a1 = Address(email_address="address1")
         u1 = User(name='jack', address=a1)
-        
+
         sess.add(u1)
         sess.commit()
         sess.expunge(u1)
-        
+
         u2= User(name='ed')
         # the _SingleParent extension sets the backref get to "active" !
         # u1 gets loaded and deleted
         u2.address = a1
         sess.commit()
         assert sess.query(User).count() == 1
-        
-    
+
+
 class M2MScalarMoveTest(_fixtures.FixtureTest):
     run_inserts = None
 
@@ -452,25 +452,25 @@ class M2MScalarMoveTest(_fixtures.FixtureTest):
             'keyword':relationship(Keyword, secondary=item_keywords, uselist=False, backref=backref("item", uselist=False))
         })
         mapper(Keyword, keywords)
-    
+
     @testing.resolve_artifact_names
     def test_collection_move_preloaded(self):
         sess = sessionmaker()()
-        
+
         k1 = Keyword(name='k1')
         i1 = Item(description='i1', keyword=k1)
         i2 = Item(description='i2')
 
         sess.add_all([i1, i2, k1])
         sess.commit() # everything is expired
-        
+
         # load i1.keyword
         assert i1.keyword is k1
-        
+
         i2.keyword = k1
 
         assert k1.item is i2
-        
+
         # nothing happens.
         assert i1.keyword is k1
         assert i2.keyword is k1
index b36f52ac26c72f8ff6a81135f52976ce5c652e78..ccc5120f85a46844d37def5f7c01973a03273677 100644 (file)
@@ -35,7 +35,7 @@ class O2MCascadeDeleteOrphanTest(_base.MappedTest):
               Column('address_id', Integer, ForeignKey('addresses.id')),
               Column('data', String(30))
         )
-        
+
     @classmethod
     def setup_classes(cls):
         class User(_base.ComparableEntity):
@@ -46,7 +46,7 @@ class O2MCascadeDeleteOrphanTest(_base.MappedTest):
             pass
         class Dingaling(_base.ComparableEntity):
             pass
-            
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_mappers(cls):
@@ -55,11 +55,11 @@ class O2MCascadeDeleteOrphanTest(_base.MappedTest):
         mapper(User, users, properties={
            'addresses':relationship(Address,
                             cascade='all, delete-orphan', backref='user'),
-                            
+
            'orders':relationship(Order,
                         cascade='all, delete-orphan', order_by=orders.c.id)
         })
-        
+
         mapper(Dingaling, dingalings, properties={
             'address' : relationship(Address)
         })
@@ -122,22 +122,22 @@ class O2MCascadeDeleteOrphanTest(_base.MappedTest):
         assert o2 in sess
         assert o3 in sess
         sess.commit()
-    
+
     @testing.resolve_artifact_names
     def test_remove_pending_from_collection(self):
         sess = Session()
-        
+
         u = User(name='jack')
         sess.add(u)
         sess.commit()
-        
+
         o1 = Order()
         u.orders.append(o1)
         assert o1 in sess
         u.orders.remove(o1)
         assert o1 not in sess
-        
-        
+
+
     @testing.resolve_artifact_names
     def test_delete(self):
         sess = create_session()
@@ -207,14 +207,14 @@ class O2MCascadeDeleteOrphanTest(_base.MappedTest):
     def test_cascade_nosideeffects(self):
         """test that cascade leaves the state of unloaded
         scalars/collections unchanged."""
-        
+
         sess = create_session()
         u = User(name='jack')
         sess.add(u)
         assert 'orders' not in u.__dict__
 
         sess.flush()
-        
+
         assert 'orders' not in u.__dict__
 
         a = Address(email_address='foo@bar.com')
@@ -222,14 +222,14 @@ class O2MCascadeDeleteOrphanTest(_base.MappedTest):
         assert 'user' not in a.__dict__
         a.user = u
         sess.flush()
-        
+
         d = Dingaling(data='d1')
         d.address_id = a.id
         sess.add(d)
         assert 'address' not in d.__dict__
         sess.flush()
         assert d.address is a
-        
+
     @testing.resolve_artifact_names
     def test_cascade_delete_plusorphans(self):
         sess = create_session()
@@ -268,7 +268,7 @@ class O2MCascadeDeleteOrphanTest(_base.MappedTest):
 
 class O2MCascadeDeleteNoOrphanTest(_base.MappedTest):
     run_inserts = None
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('users', metadata,
@@ -280,14 +280,14 @@ class O2MCascadeDeleteNoOrphanTest(_base.MappedTest):
             Column('user_id', Integer, ForeignKey('users.id')),
             Column('description', String(30))
         )
-    
+
     @classmethod
     def setup_classes(cls):
         class User(_base.ComparableEntity):
             pass
         class Order(_base.ComparableEntity):
             pass
-            
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_mappers(cls):
@@ -315,7 +315,7 @@ class O2MCascadeDeleteNoOrphanTest(_base.MappedTest):
 
 class O2OSingleParentTest(_fixtures.FixtureTest):
     run_inserts = None
-    
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_mappers(cls):
@@ -334,12 +334,12 @@ class O2OSingleParentTest(_fixtures.FixtureTest):
         u1.address = a2
         assert u1.address is not a1
         assert a1.user is None
-        
+
 class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
     """Test related item not present in session, commit proceeds."""
 
     run_inserts = None
-    
+
     @testing.resolve_artifact_names
     def _one_to_many_fixture(self, o2m_cascade=True, 
                                     m2o_cascade=True, 
@@ -347,7 +347,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
                                     m2o=False,
                                     o2m_cascade_backrefs=True,
                                     m2o_cascade_backrefs=True):
-        
+
         if o2m:
             if m2o:
                 addresses_rel = {'addresses':relationship(
@@ -359,7 +359,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
                                             cascade_backrefs=m2o_cascade_backrefs
                                         )
                                 )}
-                                
+
             else:
                 addresses_rel = {'addresses':relationship(
                                 Address, 
@@ -376,7 +376,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         else:
             addresses_rel = {}
             user_rel = {}
-        
+
         mapper(User, users, properties=addresses_rel)
         mapper(Address, addresses, properties=user_rel)
 
@@ -387,7 +387,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
                                     bkd=False,
                                     fwd_cascade_backrefs=True,
                                     bkd_cascade_backrefs=True):
-        
+
         if fwd:
             if bkd:
                 keywords_rel = {'keywords':relationship(
@@ -400,7 +400,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
                                             cascade_backrefs=bkd_cascade_backrefs
                                         )
                                 )}
-                                
+
             else:
                 keywords_rel = {'keywords':relationship(
                                 Keyword, 
@@ -419,7 +419,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         else:
             keywords_rel = {}
             items_rel = {}
-        
+
         mapper(Item, items, properties=keywords_rel)
         mapper(Keyword, keywords, properties=items_rel)
 
@@ -434,7 +434,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         assert u1 in sess
         assert a1 in sess
         sess.flush()
-        
+
     @testing.resolve_artifact_names
     def test_o2m_only_child_transient(self):
         self._one_to_many_fixture(o2m=True, m2o=False, o2m_cascade=False)
@@ -457,9 +457,9 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         a1 = Address(email_address='a1')
         sess.add(a1)
         sess.flush()
-        
+
         sess.expunge_all()
-        
+
         u1.addresses.append(a1)
         sess.add(u1)
         assert u1 in sess
@@ -467,7 +467,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         assert_raises_message(
             sa_exc.SAWarning, "not in session", sess.flush
         )
-        
+
     @testing.resolve_artifact_names
     def test_o2m_backref_child_pending(self):
         self._one_to_many_fixture(o2m=True, m2o=True)
@@ -511,7 +511,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
             sess.commit()
         go()
         eq_(u1.addresses, [])
-        
+
     @testing.resolve_artifact_names
     def test_o2m_backref_child_expunged(self):
         self._one_to_many_fixture(o2m=True, m2o=True, 
@@ -521,7 +521,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         a1 = Address(email_address='a1')
         sess.add(a1)
         sess.flush()
-        
+
         sess.add(u1)
         u1.addresses.append(a1)
         sess.expunge(a1)
@@ -540,7 +540,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         a1 = Address(email_address='a1')
         sess.add(a1)
         sess.flush()
-        
+
         sess.add(u1)
         u1.addresses.append(a1)
         sess.expunge(a1)
@@ -585,7 +585,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         u1 = User(name='u1')
         sess.add(u1)
         sess.flush()
-        
+
         a1 = Address(email_address='a1')
         a1.user = u1
         sess.add(a1)
@@ -629,7 +629,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         u1 = User(name='u1')
         sess.add(u1)
         sess.flush()
-        
+
         a1 = Address(email_address='a1')
         a1.user = u1
         sess.add(a1)
@@ -645,7 +645,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         self._one_to_many_fixture(o2m=True, m2o=True, m2o_cascade=False)
         sess = Session()
         u1 = User(name='u1')
-        
+
         a1 = Address(email_address='a1')
         a1.user = u1
         sess.add(a1)
@@ -665,7 +665,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         u1 = User(name='u1')
         sess.add(u1)
         sess.flush()
-        
+
         a1 = Address(email_address='a1')
         a1.user = u1
         sess.add(a1)
@@ -690,7 +690,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         assert i1 in sess
         assert k1 in sess
         sess.flush()
-        
+
     @testing.resolve_artifact_names
     def test_m2m_only_child_transient(self):
         self._many_to_many_fixture(fwd=True, bkd=False, fwd_cascade=False)
@@ -713,9 +713,9 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         k1 = Keyword(name='k1')
         sess.add(k1)
         sess.flush()
-        
+
         sess.expunge_all()
-        
+
         i1.keywords.append(k1)
         sess.add(i1)
         assert i1 in sess
@@ -723,7 +723,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         assert_raises_message(
             sa_exc.SAWarning, "not in session", sess.flush
         )
-        
+
     @testing.resolve_artifact_names
     def test_m2m_backref_child_pending(self):
         self._many_to_many_fixture(fwd=True, bkd=True)
@@ -767,7 +767,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
             sess.commit()
         go()
         eq_(i1.keywords, [])
-        
+
     @testing.resolve_artifact_names
     def test_m2m_backref_child_expunged(self):
         self._many_to_many_fixture(fwd=True, bkd=True, 
@@ -777,7 +777,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         k1 = Keyword(name='k1')
         sess.add(k1)
         sess.flush()
-        
+
         sess.add(i1)
         i1.keywords.append(k1)
         sess.expunge(k1)
@@ -796,7 +796,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
         k1 = Keyword(name='k1')
         sess.add(k1)
         sess.flush()
-        
+
         sess.add(i1)
         i1.keywords.append(k1)
         sess.expunge(k1)
@@ -811,7 +811,7 @@ class NoSaveCascadeFlushTest(_fixtures.FixtureTest):
 class NoSaveCascadeBackrefTest(_fixtures.FixtureTest):
     """test that backrefs don't force save-update cascades to occur
     when the cascade initiated from the forwards side."""
-    
+
     @testing.resolve_artifact_names
     def test_unidirectional_cascade_o2m(self):
         mapper(Order, orders)
@@ -819,17 +819,17 @@ class NoSaveCascadeBackrefTest(_fixtures.FixtureTest):
             orders = relationship(
                 Order, backref=backref("user", cascade=None))
         ))
-        
+
         sess = create_session()
-        
+
         o1 = Order()
         sess.add(o1)
         u1 = User(orders=[o1])
         assert u1 not in sess
         assert o1 in sess
-        
+
         sess.expunge_all()
-        
+
         o1 = Order()
         u1 = User(orders=[o1])
         sess.add(o1)
@@ -842,16 +842,16 @@ class NoSaveCascadeBackrefTest(_fixtures.FixtureTest):
             'user':relationship(User, backref=backref("orders", cascade=None))
         })
         mapper(User, users)
-        
+
         sess = create_session()
-        
+
         u1 = User()
         sess.add(u1)
         o1 = Order()
         o1.user = u1
         assert o1 not in sess
         assert u1 in sess
-        
+
         sess.expunge_all()
 
         u1 = User()
@@ -876,9 +876,9 @@ class NoSaveCascadeBackrefTest(_fixtures.FixtureTest):
         i1.keywords.append(k1)
         assert i1 in sess
         assert k1 not in sess
-        
+
         sess.expunge_all()
-        
+
         i1 = Item()
         k1 = Keyword()
         sess.add(i1)
@@ -886,7 +886,7 @@ class NoSaveCascadeBackrefTest(_fixtures.FixtureTest):
         assert i1 in sess
         assert k1 not in sess
 
-    
+
 class M2OCascadeDeleteOrphanTestOne(_base.MappedTest):
 
     @classmethod
@@ -920,7 +920,7 @@ class M2OCascadeDeleteOrphanTestOne(_base.MappedTest):
             pass
         class Foo(_fixtures.Base):
             pass
-            
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_mappers(cls):
@@ -960,8 +960,8 @@ class M2OCascadeDeleteOrphanTestOne(_base.MappedTest):
         """test a bug introduced by r6711"""
 
         sess = sessionmaker(expire_on_commit=True)()
-        
-        
+
+
         u1 = User(name='jack', foo=Foo(data='f1'))
         sess.add(u1)
         sess.commit()
@@ -975,7 +975,7 @@ class M2OCascadeDeleteOrphanTestOne(_base.MappedTest):
             attributes.get_history(u1, 'foo'),
             ([None], (), [attributes.PASSIVE_NO_RESULT])
         )
-        
+
         sess.add(u1)
         assert u1 in sess
         sess.commit()
@@ -987,15 +987,15 @@ class M2OCascadeDeleteOrphanTestOne(_base.MappedTest):
 
         sess = sessionmaker(expire_on_commit=False)()
         p1, p2 = Pref(data='p1'), Pref(data='p2')
-        
-        
+
+
         u = User(name='jack', pref=p1)
         sess.add(u)
         sess.commit()
         sess.close()
 
         u.pref = p2
-        
+
         sess.add(u)
         assert p1 in sess
         assert p2 in sess
@@ -1057,13 +1057,13 @@ class M2OCascadeDeleteOrphanTestTwo(_base.MappedTest):
                             test_needs_autoincrement=True),
               Column('data', String(50)),
               Column('t2id', Integer, ForeignKey('t2.id')))
-              
+
         Table('t2', metadata,
               Column('id', Integer, primary_key=True,
                                 test_needs_autoincrement=True),
               Column('data', String(50)),
               Column('t3id', Integer, ForeignKey('t3.id')))
-              
+
         Table('t3', metadata,
               Column('id', Integer, primary_key=True,
                                 test_needs_autoincrement=True),
@@ -1146,7 +1146,7 @@ class M2OCascadeDeleteOrphanTestTwo(_base.MappedTest):
     def test_single_parent_raise(self):
 
         sess = create_session()
-        
+
         y = T2(data='T2a')
         x = T1(data='T1a', t2=y)
         assert_raises(sa_exc.InvalidRequestError, T1, data='T1b', t2=y)
@@ -1155,13 +1155,13 @@ class M2OCascadeDeleteOrphanTestTwo(_base.MappedTest):
     def test_single_parent_backref(self):
 
         sess = create_session()
-        
+
         y = T3(data='T3a')
         x = T2(data='T2a', t3=y)
 
         # cant attach the T3 to another T2
         assert_raises(sa_exc.InvalidRequestError, T2, data='T2b', t3=y)
-        
+
         # set via backref tho is OK, unsets from previous parent
         # first
         z = T2(data='T2b')
@@ -1178,13 +1178,13 @@ class M2OCascadeDeleteNoOrphanTest(_base.MappedTest):
               test_needs_autoincrement=True), 
               Column('data',String(50)), 
               Column('t2id', Integer, ForeignKey('t2.id')))
-              
+
         Table('t2', metadata, 
             Column('id', Integer, primary_key=True,
               test_needs_autoincrement=True), 
               Column('data',String(50)), 
               Column('t3id', Integer, ForeignKey('t3.id')))
-              
+
         Table('t3', metadata, 
             Column('id', Integer, primary_key=True,
               test_needs_autoincrement=True), 
@@ -1310,13 +1310,13 @@ class M2MCascadeTest(_base.MappedTest):
                             test_needs_autoincrement=True),
             Column('data', String(30)),
             test_needs_fk=True
-            
+
             )
         Table('atob', metadata,
             Column('aid', Integer, ForeignKey('a.id')),
             Column('bid', Integer, ForeignKey('b.id')),
             test_needs_fk=True
-            
+
             )
         Table('c', metadata,
               Column('id', Integer, primary_key=True,
@@ -1324,7 +1324,7 @@ class M2MCascadeTest(_base.MappedTest):
               Column('data', String(30)),
               Column('bid', Integer, ForeignKey('b.id')),
               test_needs_fk=True
-              
+
               )
 
     @classmethod
@@ -1433,7 +1433,7 @@ class M2MCascadeTest(_base.MappedTest):
         sess = create_session()
         b1 =B(data='b1')
         a1 = A(data='a1', bs=[b1])
-        
+
         assert_raises(sa_exc.InvalidRequestError,
                 A, data='a2', bs=[b1]
             )
@@ -1441,7 +1441,7 @@ class M2MCascadeTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_single_parent_backref(self):
         """test that setting m2m via a uselist=False backref bypasses the single_parent raise"""
-        
+
         mapper(A, a, properties={
             'bs':relationship(B, 
                 secondary=atob, 
@@ -1453,12 +1453,12 @@ class M2MCascadeTest(_base.MappedTest):
         sess = create_session()
         b1 =B(data='b1')
         a1 = A(data='a1', bs=[b1])
-        
+
         assert_raises(
             sa_exc.InvalidRequestError,
             A, data='a2', bs=[b1]
         )
-        
+
         a2 = A(data='a2')
         b1.a = a2
         assert b1 not in a1.bs
@@ -1475,7 +1475,7 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest):
                 'addresses':relationship(Address, backref='user', 
                             cascade_backrefs=False)
         })
-        
+
         mapper(Dingaling, dingalings, properties={
                 'address' : relationship(Address, backref='dingalings', 
                             cascade_backrefs=False)
@@ -1484,10 +1484,10 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_o2m_basic(self):
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
-        
+
         a1 = Address(email_address='a1')
         a1.user = u1
         assert a1 not in sess
@@ -1496,29 +1496,29 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_o2m_commit_warns(self):
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
-        
+
         a1 = Address(email_address='a1')
         a1.user = u1
-        
+
         assert_raises_message(
             sa_exc.SAWarning,
             "not in session",
             sess.commit
         )
-        
+
         assert a1 not in sess
-        
+
 
     @testing.resolve_artifact_names
     def test_o2m_flag_on_backref(self):
         sess = Session()
-        
+
         a1 = Address(email_address='a1')
         sess.add(a1)
-        
+
         d1 = Dingaling()
         d1.address = a1
         assert d1 in a1.dingalings
@@ -1533,7 +1533,7 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest):
         a1 = Address(email_address='a1')
         d1 = Dingaling()
         sess.add(d1)
-        
+
         a1.dingalings.append(d1)
         assert a1 not in sess
 
@@ -1543,7 +1543,7 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest):
 
         a1 = Address(email_address='a1')
         sess.add(a1)
-        
+
         u1 = User(name='u1')
         u1.addresses.append(a1)
         assert u1 in sess
@@ -1555,7 +1555,7 @@ class NoBackrefCascadeTest(_fixtures.FixtureTest):
         a1 = Address(email_address='a1')
         d1 = Dingaling()
         sess.add(d1)
-        
+
         a1.dingalings.append(d1)
         assert a1 not in sess
 
@@ -1592,17 +1592,17 @@ class PendingOrphanTestSingleLevel(_base.MappedTest):
             pass
         class Order(_fixtures.Base):
             pass
-            
+
     @testing.resolve_artifact_names
     def test_pending_standalone_orphan(self):
         """Standalone 'orphan' objects can now be persisted, if the underlying 
-        constraints of the database allow it.   
-        
+        constraints of the database allow it.
+
         This now supports persisting of objects based on foreign key
         values alone.
-        
+
         """
-        
+
         mapper(Order, orders)
         mapper(Address, addresses)
         mapper(User, users, properties=dict(
@@ -1611,13 +1611,13 @@ class PendingOrphanTestSingleLevel(_base.MappedTest):
             orders=relationship(Order, cascade='all, delete-orphan')
         ))
         s = Session()
-        
+
         # the standalone Address goes in, its foreign key
         # allows NULL
         a = Address()
         s.add(a)
         s.commit()
-        
+
         # the standalone Order does not.
         o = Order()
         s.add(o)
@@ -1633,7 +1633,7 @@ class PendingOrphanTestSingleLevel(_base.MappedTest):
         s.add(o)
         s.commit()
         assert o in s and o not in s.new
-        
+
 
     @testing.resolve_artifact_names
     def test_pending_collection_expunge(self):
@@ -1683,11 +1683,11 @@ class PendingOrphanTestSingleLevel(_base.MappedTest):
 
 class PendingOrphanTestTwoLevel(_base.MappedTest):
     """test usages stated at
-    
+
     http://article.gmane.org/gmane.comp.python.sqlalchemy.user/3085
     http://article.gmane.org/gmane.comp.python.sqlalchemy.user/3119
     """
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('order', metadata,
@@ -1701,7 +1701,7 @@ class PendingOrphanTestTwoLevel(_base.MappedTest):
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('item_id', Integer, ForeignKey('item.id'), nullable=False)
         )
-    
+
     @classmethod
     def setup_classes(cls):
         class Order(_base.ComparableEntity):
@@ -1710,7 +1710,7 @@ class PendingOrphanTestTwoLevel(_base.MappedTest):
             pass
         class Attribute(_base.ComparableEntity):
             pass
-    
+
     @testing.resolve_artifact_names
     def test_singlelevel_remove(self):
         mapper(Order, order, properties={
@@ -1720,13 +1720,13 @@ class PendingOrphanTestTwoLevel(_base.MappedTest):
         s = Session()
         o1 = Order()
         s.add(o1)
-        
+
         i1 = Item()
         o1.items.append(i1)
         o1.items.remove(i1)
         s.commit()
         assert i1 not in o1.items
-        
+
     @testing.resolve_artifact_names
     def test_multilevel_remove(self):
         mapper(Order, order, properties={
@@ -1748,7 +1748,7 @@ class PendingOrphanTestTwoLevel(_base.MappedTest):
 
         assert i1 in s
         assert a1 in s
-        
+
         # i1 is an orphan so the operation
         # removes 'i1'.  The operation
         # cascades down to 'a1'.
@@ -1756,7 +1756,7 @@ class PendingOrphanTestTwoLevel(_base.MappedTest):
 
         assert i1 not in s
         assert a1 not in s
-        
+
         s.commit()
         assert o1 in s
         assert a1 not in s
@@ -1766,7 +1766,7 @@ class PendingOrphanTestTwoLevel(_base.MappedTest):
 class DoubleParentO2MOrphanTest(_base.MappedTest):
     """Test orphan behavior on an entity that requires
     two parents via many-to-one (one-to-many collection.).
-    
+
     """
 
     @classmethod
@@ -1779,7 +1779,7 @@ class DoubleParentO2MOrphanTest(_base.MappedTest):
             Column('account_id', Integer,primary_key=True,
                                     test_needs_autoincrement=True),
             Column('balance', Integer))
-            
+
         Table('customers', meta,
             Column('customer_id', Integer,primary_key=True,
                                     test_needs_autoincrement=True),
@@ -1793,7 +1793,7 @@ class DoubleParentO2MOrphanTest(_base.MappedTest):
     def test_double_parent_expunge_o2m(self):
         """test the delete-orphan uow event for multiple delete-orphan
         parent relationships."""
-        
+
         class Customer(_fixtures.Base):
             pass
         class Account(_fixtures.Base):
@@ -1871,11 +1871,11 @@ class DoubleParentO2MOrphanTest(_base.MappedTest):
         assert c not in s, \
             'Should expunge customer when both parents are gone'
 
-        
+
 class DoubleParentM2OOrphanTest(_base.MappedTest):
     """Test orphan behavior on an entity that requires
     two parents via one-to-many (many-to-one reference to the orphan).
-    
+
     """
 
     @classmethod
@@ -2013,9 +2013,9 @@ class CollectionAssignmentOrphanTest(_base.MappedTest):
 class O2MConflictTest(_base.MappedTest):
     """test that O2M dependency detects a change in parent, does the
     right thing, and updates the collection/attribute.
-    
+
     """
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table("parent", metadata,
@@ -2028,18 +2028,18 @@ class O2MConflictTest(_base.MappedTest):
             Column('parent_id', Integer, ForeignKey('parent.id'),
                                     nullable=False)
         )
-    
+
     @classmethod
     def setup_classes(cls):
         class Parent(_base.ComparableEntity):
             pass
         class Child(_base.ComparableEntity):
             pass
-    
+
     @testing.resolve_artifact_names
     def _do_move_test(self, delete_old):
         sess = create_session()
-        
+
         p1, p2, c1 = Parent(), Parent(), Child()
         if Parent.child.property.uselist:
             p1.child.append(c1)
@@ -2047,10 +2047,10 @@ class O2MConflictTest(_base.MappedTest):
             p1.child = c1
         sess.add_all([p1, c1])
         sess.flush()
-        
+
         if delete_old:
             sess.delete(p1)
-        
+
         if Parent.child.property.uselist:
             p2.child.append(c1)
         else:
@@ -2086,7 +2086,7 @@ class O2MConflictTest(_base.MappedTest):
         mapper(Child, child)
         self._do_move_test(True)
         self._do_move_test(False)
-        
+
     @testing.resolve_artifact_names
     def test_o2o_delcascade_delete_old(self):
         mapper(Parent, parent, properties={
@@ -2138,7 +2138,7 @@ class O2MConflictTest(_base.MappedTest):
         })
         self._do_move_test(True)
         self._do_move_test(False)
-        
+
 
 class PartialFlushTest(_base.MappedTest):
     """test cascade behavior as it relates to object lists passed to flush()."""
@@ -2218,7 +2218,7 @@ class PartialFlushTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_circular_sort(self):
         """test ticket 1306"""
-        
+
         class Base(_base.ComparableEntity):
             pass
         class Parent(Base):
@@ -2246,9 +2246,9 @@ class PartialFlushTest(_base.MappedTest):
         c1, c2, c3 = Child(), Child(), Child()
         p1.children = [c1, c2, c3]
         sess.add(p1)
-        
+
         sess.flush([c1])
         assert p1 in sess.new
         assert c1 not in sess.new
         assert c2 in sess.new
-        
+
index 540213745bd390b0e8b5de043ca9242f83de801a..8e17b2f2bf41fc02616ade5b7a87562b42376f8a 100644 (file)
@@ -175,7 +175,7 @@ class CollectionsTest(_base.ORMTest):
                 def invalid():
                     direct[slice(0, 6, 2)] = [creator()]
                 assert_raises(ValueError, invalid)
-                
+
         if hasattr(direct, '__delitem__'):
             e = creator()
             direct.append(e)
@@ -200,7 +200,7 @@ class CollectionsTest(_base.ORMTest):
                 del direct[::2]
                 del control[::2]
                 assert_eq()
-            
+
         if hasattr(direct, 'remove'):
             e = creator()
             direct.append(e)
@@ -209,21 +209,21 @@ class CollectionsTest(_base.ORMTest):
             direct.remove(e)
             control.remove(e)
             assert_eq()
-        
+
         if hasattr(direct, '__setitem__') or hasattr(direct, '__setslice__'):
-            
+
             values = [creator(), creator()]
             direct[:] = values
             control[:] = values
             assert_eq()
-            
+
             # test slice assignment where
             # slice size goes over the number of items
             values = [creator(), creator()]
             direct[1:3] = values
             control[1:3] = values
             assert_eq()
-            
+
             values = [creator(), creator()]
             direct[0:1] = values
             control[0:1] = values
@@ -248,7 +248,7 @@ class CollectionsTest(_base.ORMTest):
             direct[1::2] = values
             control[1::2] = values
             assert_eq()
-            
+
             values = [creator(), creator()]
             direct[-1:-3] = values
             control[-1:-3] = values
@@ -258,7 +258,7 @@ class CollectionsTest(_base.ORMTest):
             direct[-2:-1] = values
             control[-2:-1] = values
             assert_eq()
-            
+
 
         if hasattr(direct, '__delitem__') or hasattr(direct, '__delslice__'):
             for i in range(1, 4):
@@ -277,7 +277,7 @@ class CollectionsTest(_base.ORMTest):
             del direct[:]
             del control[:]
             assert_eq()
-        
+
         if hasattr(direct, 'extend'):
             values = [creator(), creator(), creator()]
 
@@ -377,7 +377,7 @@ class CollectionsTest(_base.ORMTest):
         self._test_list_bulk(list)
 
     def test_list_setitem_with_slices(self):
-        
+
         # this is a "list" that has no __setslice__
         # or __delslice__ methods.  The __setitem__
         # and __delitem__ must therefore accept
@@ -1453,7 +1453,7 @@ class DictHelpersTest(_base.MappedTest):
 
         p = session.query(Parent).get(pid)
 
-        
+
         eq_(set(p.children.keys()), set(['foo', 'bar']))
         cid = p.children['foo'].id
 
@@ -1544,7 +1544,7 @@ class DictHelpersTest(_base.MappedTest):
 
     def test_declarative_column_mapped(self):
         """test that uncompiled attribute usage works with column_mapped_collection"""
-        
+
         from sqlalchemy.ext.declarative import declarative_base
 
         BaseObject = declarative_base()
@@ -1553,13 +1553,13 @@ class DictHelpersTest(_base.MappedTest):
             __tablename__ = "foo"
             id = Column(Integer(), primary_key=True, test_needs_autoincrement=True)
             bar_id = Column(Integer, ForeignKey('bar.id'))
-            
+
         class Bar(BaseObject):
             __tablename__ = "bar"
             id = Column(Integer(), primary_key=True, test_needs_autoincrement=True)
             foos = relationship(Foo, collection_class=collections.column_mapped_collection(Foo.id))
             foos2 = relationship(Foo, collection_class=collections.column_mapped_collection((Foo.id, Foo.bar_id)))
-            
+
         eq_(Bar.foos.property.collection_class().keyfunc(Foo(id=3)), 3)
         eq_(Bar.foos2.property.collection_class().keyfunc(Foo(id=3, bar_id=12)), (3, 12))
 
@@ -1574,8 +1574,8 @@ class DictHelpersTest(_base.MappedTest):
                               "for argument 'mapping_spec'; got: 'a'",
                               collections.column_mapped_collection,
                               text('a'))
-        
-        
+
+
     @testing.resolve_artifact_names
     def test_column_mapped_collection(self):
         collection_class = collections.column_mapped_collection(
@@ -1760,9 +1760,9 @@ class CustomCollectionsTest(_base.MappedTest):
                 return self.data == other
             def __repr__(self):
                 return 'ListLike(%s)' % repr(self.data)
-        
+
         self._test_list(ListLike)
-        
+
     @testing.resolve_artifact_names
     def _test_list(self, listcls):
         class Parent(object):
@@ -1801,7 +1801,7 @@ class CustomCollectionsTest(_base.MappedTest):
 
         o = [Child()]
         control[1:3] = o
-        
+
         p.children[1:3] = o
         assert control == p.children
         assert control == list(p.children)
index 768d8636e691211bdb612ccaf72f0a0f9e1ecf60..46d6bb44d921cd18aa336599e275fc69a8ca4aa0 100644 (file)
@@ -61,7 +61,7 @@ class PointTest(_base.MappedTest):
             'start':sa.orm.composite(Point, edges.c.x1, edges.c.y1),
             'end': sa.orm.composite(Point, edges.c.x2, edges.c.y2)
         })
-    
+
     @testing.resolve_artifact_names
     def _fixture(self):
         sess = Session()
@@ -72,7 +72,7 @@ class PointTest(_base.MappedTest):
         sess.add(g)
         sess.commit()
         return sess
-        
+
     @testing.resolve_artifact_names
     def test_round_trip(self):
 
@@ -80,7 +80,7 @@ class PointTest(_base.MappedTest):
 
         g1 = sess.query(Graph).first()
         sess.close()
-        
+
         g = sess.query(Graph).get(g1.id)
         eq_(
             [(e.start, e.end) for e in g.edges],
@@ -88,40 +88,40 @@ class PointTest(_base.MappedTest):
                 (Point(3, 4), Point(5, 6)),
                 (Point(14, 5), Point(2, 7)),
             ]
-        )    
+        )
 
     @testing.resolve_artifact_names
     def test_detect_change(self):
         sess = self._fixture()
-        
+
         g = sess.query(Graph).first()
         g.edges[1].end = Point(18, 4)
         sess.commit()
 
         e = sess.query(Edge).get(g.edges[1].id)
         eq_(e.end, Point(18, 4))
-        
+
     @testing.resolve_artifact_names
     def test_eager_load(self):
         sess = self._fixture()
 
         g = sess.query(Graph).first()
         sess.close()
-        
+
         def go():
             g2 = sess.query(Graph).\
                   options(sa.orm.joinedload('edges')).\
                   get(g.id)
-            
+
             eq_(
                 [(e.start, e.end) for e in g2.edges],
                 [
                     (Point(3, 4), Point(5, 6)),
                     (Point(14, 5), Point(2, 7)),
                 ]
-            )    
+            )
         self.assert_sql_count(testing.db, go, 1)
-    
+
     @testing.resolve_artifact_names
     def test_comparator(self):
         sess = self._fixture()
@@ -149,12 +149,12 @@ class PointTest(_base.MappedTest):
             sess.query(Edge.start, Edge.end).all(), 
             [(3, 4, 5, 6), (14, 5, 2, 7)]
         )
-    
+
     @testing.resolve_artifact_names
     def test_delete(self):
         sess = self._fixture()
         g = sess.query(Graph).first()
-        
+
         e = g.edges[1]
         del e.end
         sess.flush()
@@ -166,19 +166,19 @@ class PointTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_save_null(self):
         """test saving a null composite value
-        
+
         See google groups thread for more context:
         http://groups.google.com/group/sqlalchemy/browse_thread/thread/0c6580a1761b2c29
-        
+
         """
         sess = Session()
         g = Graph(id=1)
         e = Edge(None, None)
         g.edges.append(e)
-        
+
         sess.add(g)
         sess.commit()
-        
+
         g2 = sess.query(Graph).get(1)
         assert g2.edges[-1].start.x is None
         assert g2.edges[-1].start.y is None
@@ -191,12 +191,12 @@ class PointTest(_base.MappedTest):
         sess.expire(e)
         assert 'start' not in e.__dict__
         assert e.start == Point(3, 4)
-    
+
     @testing.resolve_artifact_names
     def test_default_value(self):
         e = Edge()
         eq_(e.start, None)
-        
+
 class PrimaryKeyTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -205,7 +205,7 @@ class PrimaryKeyTest(_base.MappedTest):
                         test_needs_autoincrement=True),
             Column('version_id', Integer, primary_key=True, nullable=True),
             Column('name', String(30)))
-    
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_mappers(cls):
@@ -229,7 +229,7 @@ class PrimaryKeyTest(_base.MappedTest):
         mapper(Graph, graphs, properties={
             'version':sa.orm.composite(Version, graphs.c.id,
                                        graphs.c.version_id)})
-    
+
 
     @testing.resolve_artifact_names
     def _fixture(self):
@@ -238,13 +238,13 @@ class PrimaryKeyTest(_base.MappedTest):
         sess.add(g)
         sess.commit()
         return sess
-        
+
     @testing.resolve_artifact_names
     def test_get_by_col(self):
 
         sess = self._fixture()
         g = sess.query(Graph).first()
-        
+
         g2 = sess.query(Graph).get([g.id, g.version_id])
         eq_(g.version, g2.version)
 
@@ -252,7 +252,7 @@ class PrimaryKeyTest(_base.MappedTest):
     def test_get_by_composite(self):
         sess = self._fixture()
         g = sess.query(Graph).first()
-        
+
         g2 = sess.query(Graph).get(Version(g.id, g.version_id))
         eq_(g.version, g2.version)
 
@@ -272,7 +272,7 @@ class PrimaryKeyTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_null_pk(self):
         sess = Session()
-        
+
         # test pk with one column NULL
         # only sqlite can really handle this
         g = Graph(Version(2, None))
@@ -280,7 +280,7 @@ class PrimaryKeyTest(_base.MappedTest):
         sess.commit()
         g2 = sess.query(Graph).filter_by(version=Version(2, None)).one()
         eq_(g.version, g2.version)
-    
+
 class DefaultsTest(_base.MappedTest):
 
     @classmethod
@@ -323,7 +323,7 @@ class DefaultsTest(_base.MappedTest):
                                 foobars.c.x3, 
                                 foobars.c.x4)
         ))
-        
+
     @testing.resolve_artifact_names
     def test_attributes_with_defaults(self):
 
@@ -334,12 +334,12 @@ class DefaultsTest(_base.MappedTest):
         sess.flush()
 
         assert f1.foob == FBComposite(2, 5, 15, None)
-        
+
         f2 = Foobar()
         sess.add(f2)
         sess.flush()
         assert f2.foob == FBComposite(2, None, 15, None)
-    
+
     @testing.resolve_artifact_names
     def test_set_composite_values(self):
         sess = Session()
@@ -347,9 +347,9 @@ class DefaultsTest(_base.MappedTest):
         f1.foob = FBComposite(None, 5, None, None)
         sess.add(f1)
         sess.flush()
-        
+
         assert f1.foob == FBComposite(2, 5, 15, None)
-    
+
 class MappedSelectTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -367,7 +367,7 @@ class MappedSelectTest(_base.MappedTest):
             Column('v1', String(20)),
             Column('v2', String(20)),
         )
-    
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_mappers(cls):
@@ -404,7 +404,7 @@ class MappedSelectTest(_base.MappedTest):
                                             desc_values.c.v2),
 
         })
-        
+
     @testing.resolve_artifact_names
     def test_set_composite_attrs_via_selectable(self):
         session = Session()
index e5e6579330c818de130ecff4d51a330f9f1e4c0b..6aa1eaa1a984df7580226827482d955f32f06af9 100644 (file)
@@ -65,7 +65,7 @@ class SelfReferentialTest(_base.MappedTest):
 
         test that the circular dependency sort can assemble a many-to-one
         dependency processor when only the object on the "many" side is
-        actually in the list of modified objects.  
+        actually in the list of modified objects.
 
         """
         mapper(C1, t1, properties={
@@ -111,7 +111,7 @@ class SelfReferentialTest(_base.MappedTest):
         mapper(C1, t1, properties={
             'children':relationship(C1)
         })
-        
+
         sess = create_session()
         c1 = C1()
         c2 = C1()
@@ -119,14 +119,14 @@ class SelfReferentialTest(_base.MappedTest):
         sess.add(c1)
         sess.flush()
         assert c2.parent_c1 == c1.c1
-        
+
         sess.delete(c1)
         sess.flush()
         assert c2.parent_c1 is None
-        
+
         sess.expire_all()
         assert c2.parent_c1 is None
-        
+
 class SelfReferentialNoPKTest(_base.MappedTest):
     """A self-referential relationship that joins on a column other than the primary key column"""
 
@@ -300,7 +300,7 @@ class InheritTestTwo(_base.MappedTest):
 
 class BiDirectionalManyToOneTest(_base.MappedTest):
     run_define_tables = 'each'
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('t1', metadata,
@@ -517,7 +517,7 @@ class OneToManyManyToOneTest(_base.MappedTest):
 
     """
     run_define_tables = 'each'
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('ball', metadata,
@@ -618,7 +618,7 @@ class OneToManyManyToOneTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_post_update_backref(self):
         """test bidirectional post_update."""
-        
+
         mapper(Ball, ball)
         mapper(Person, person, properties=dict(
             balls=relationship(Ball,
@@ -629,20 +629,20 @@ class OneToManyManyToOneTest(_base.MappedTest):
            favorite=relationship(Ball,
                              primaryjoin=person.c.favorite_ball_id == ball.c.id,
                              remote_side=person.c.favorite_ball_id)
-            
+
             ))
-        
+
         sess = sessionmaker()()
         p1 = Person(data='p1')
         p2 = Person(data='p2')
         p3 = Person(data='p3')
-        
+
         b1 = Ball(data='b1')
-        
+
         b1.person = p1
         sess.add_all([p1, p2, p3])
         sess.commit()
-        
+
         # switch here.  the post_update
         # on ball.person can't get tripped up
         # by the fact that there's a "reverse" prop.
@@ -658,7 +658,7 @@ class OneToManyManyToOneTest(_base.MappedTest):
         eq_(
             p3, b1.person
         )
-        
+
 
 
     @testing.resolve_artifact_names
@@ -724,9 +724,9 @@ class OneToManyManyToOneTest(_base.MappedTest):
             ),
 
         )
-        
+
         sess.delete(p)
-        
+
         self.assert_sql_execution(testing.db, sess.flush, 
             CompiledSQL("UPDATE ball SET person_id=:person_id "
                 "WHERE ball.id = :ball_id",
@@ -750,8 +750,8 @@ class OneToManyManyToOneTest(_base.MappedTest):
 
 class SelfReferentialPostUpdateTest(_base.MappedTest):
     """Post_update on a single self-referential mapper.
-    
-    
+
+
     """
 
     @classmethod
@@ -835,7 +835,7 @@ class SelfReferentialPostUpdateTest(_base.MappedTest):
         session.flush()
 
         remove_child(root, cats)
-        
+
         # pre-trigger lazy loader on 'cats' to make the test easier
         cats.children
         self.assert_sql_execution(
@@ -854,7 +854,7 @@ class SelfReferentialPostUpdateTest(_base.MappedTest):
              "WHERE node.id = :node_id",
              lambda ctx:{'next_sibling_id':None, 'node_id':cats.id}),
             ),
-             
+
             CompiledSQL("DELETE FROM node WHERE node.id = :id",
              lambda ctx:[{'id':cats.id}])
         )
@@ -981,7 +981,7 @@ class SelfReferentialPostUpdateTest3(_base.MappedTest):
         mapper(Child, child, properties={
             'parent':relationship(Child, remote_side=child.c.id)
         })
-        
+
         session = create_session()
         p1 = Parent('p1')
         c1 = Child('c1')
@@ -989,7 +989,7 @@ class SelfReferentialPostUpdateTest3(_base.MappedTest):
         p1.children =[c1, c2]
         c2.parent = c1
         p1.child = c2
-        
+
         session.add_all([p1, c1, c2])
         session.flush()
 
@@ -998,18 +998,18 @@ class SelfReferentialPostUpdateTest3(_base.MappedTest):
         p2.children = [c3]
         p2.child = c3
         session.add(p2)
-        
+
         session.delete(c2)
         p1.children.remove(c2)
         p1.child = None
         session.flush()
-        
+
         p2.child = None
         session.flush()
-        
+
 class PostUpdateBatchingTest(_base.MappedTest):
     """test that lots of post update cols batch together into a single UPDATE."""
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('parent', metadata,
@@ -1037,7 +1037,7 @@ class PostUpdateBatchingTest(_base.MappedTest):
              Column('name', String(50), nullable=False),
              Column('parent_id', Integer,
                     ForeignKey('parent.id'), nullable=False))
-                    
+
         Table('child3', metadata,
            Column('id', Integer, primary_key=True,
                   test_needs_autoincrement=True),
@@ -1059,14 +1059,14 @@ class PostUpdateBatchingTest(_base.MappedTest):
         class Child3(_base.BasicEntity):
             def __init__(self, name=''):
                 self.name = name
-    
+
     @testing.resolve_artifact_names
     def test_one(self):
         mapper(Parent, parent, properties={
             'c1s':relationship(Child1, primaryjoin=child1.c.parent_id==parent.c.id),
             'c2s':relationship(Child2, primaryjoin=child2.c.parent_id==parent.c.id),
             'c3s':relationship(Child3, primaryjoin=child3.c.parent_id==parent.c.id),
-            
+
             'c1':relationship(Child1, primaryjoin=child1.c.id==parent.c.c1_id, post_update=True),
             'c2':relationship(Child2, primaryjoin=child2.c.id==parent.c.c2_id, post_update=True),
             'c3':relationship(Child3, primaryjoin=child3.c.id==parent.c.c3_id, post_update=True),
@@ -1074,20 +1074,20 @@ class PostUpdateBatchingTest(_base.MappedTest):
         mapper(Child1, child1)
         mapper(Child2, child2)
         mapper(Child3, child3)
-        
+
         sess = create_session()
-        
+
         p1 = Parent('p1')
         c11, c12, c13 = Child1('c1'), Child1('c2'), Child1('c3')
         c21, c22, c23 = Child2('c1'), Child2('c2'), Child2('c3')
         c31, c32, c33 = Child3('c1'), Child3('c2'), Child3('c3')
-        
+
         p1.c1s = [c11, c12, c13]
         p1.c2s = [c21, c22, c23]
         p1.c3s = [c31, c32, c33]
         sess.add(p1)
         sess.flush()
-        
+
         p1.c1 = c12
         p1.c2 = c23
         p1.c3 = c31
@@ -1113,4 +1113,3 @@ class PostUpdateBatchingTest(_base.MappedTest):
                 lambda ctx: {'c2_id': None, 'parent_id': p1.id, 'c1_id': None, 'c3_id': None}
             )
         )
-        
\ No newline at end of file
index f7e39a4fbd7ed5202984f567e71c7778b46eb9a9..004a401c75d4718ef1ed4f422fe7c1c0eac151e7 100644 (file)
@@ -47,7 +47,7 @@ class TriggerDefaultsTest(_base.MappedTest):
                 ),
             ):
             event.listen(dt, 'after_create', ins)
-        
+
         event.listen(dt, 'before_drop', sa.DDL("DROP TRIGGER dt_ins"))
 
         for up in (
@@ -128,16 +128,16 @@ class ExcludedDefaultsTest(_base.MappedTest):
                    Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
                    Column('col1', String(20), default="hello"),
         )
-        
+
     @testing.resolve_artifact_names
     def test_exclude(self):
         class Foo(_base.ComparableEntity):
             pass
         mapper(Foo, dt, exclude_properties=('col1',))
-    
+
         f1 = Foo()
         sess = create_session()
         sess.add(f1)
         sess.flush()
         eq_(dt.select().execute().fetchall(), [(1, "hello")])
-    
+
index 2565105a64091194d9c9d5fdc9b979eeacaf034f..400532cb28b4e2918c0c4da77fb81036c2d99ec4 100644 (file)
@@ -97,9 +97,9 @@ class QueryAlternativesTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_override_get(self):
         """MapperExtension.get()
-        
+
         x = session.query.get(5)
-        
+
         """
         from sqlalchemy.orm.query import Query
         cache = {}
@@ -111,25 +111,25 @@ class QueryAlternativesTest(_base.MappedTest):
                     x = super(MyQuery, self).get(ident)
                     cache[ident] = x
                     return x
-                    
+
         session = sessionmaker(query_cls=MyQuery)()
-        
+
         ad1 = session.query(Address).get(1)
         assert ad1 in cache.values()
-    
+
     @testing.resolve_artifact_names
     def test_load(self):
         """x = session.query(Address).load(1)
-            
+
             x = session.load(Address, 1)
-        
+
         """
 
         session = create_session()
         ad1 = session.query(Address).populate_existing().get(1)
         assert bool(ad1)
-        
-        
+
+
     @testing.resolve_artifact_names
     def test_apply_max(self):
         """Query.apply_max(col)
index a09e1304714fa888383f619f2c0bbe220706a5b2..3ef4afa7f160376d685000779b291e6278b8075e 100644 (file)
@@ -19,69 +19,69 @@ class TestDescriptor(descriptor_props.DescriptorProperty):
             self._comparator_factory = partial(comparator_factory, self)
         else:
             self._comparator_factory = lambda mapper: None
-        
+
 class DescriptorInstrumentationTest(_base.ORMTest):
     def _fixture(self):
         Base = declarative_base()
-        
+
         class Foo(Base):
             __tablename__ = 'foo'
             id = Column(Integer, primary_key=True)
-        
+
         return Foo
-    
+
     def test_fixture(self):
         Foo = self._fixture()
-        
+
         d = TestDescriptor(Foo, 'foo')
         d.instrument_class(Foo.__mapper__)
-        
+
         assert Foo.foo
 
     def test_property_wrapped_classlevel(self):
         Foo = self._fixture()
         prop = property(lambda self:None)
         Foo.foo = prop
-        
+
         d = TestDescriptor(Foo, 'foo')
         d.instrument_class(Foo.__mapper__)
-        
+
         assert Foo().foo is None
         assert Foo.foo is not prop
 
     def test_property_subclass_wrapped_classlevel(self):
         Foo = self._fixture()
-        
+
         class myprop(property):
             attr = 'bar'
 
             def method1(self):
                 return "method1"
-            
+
             def __getitem__(self, key):
                 return 'value'
 
         prop = myprop(lambda self:None)
         Foo.foo = prop
-        
+
         d = TestDescriptor(Foo, 'foo')
         d.instrument_class(Foo.__mapper__)
-        
+
         assert Foo().foo is None
         assert Foo.foo is not prop
         assert Foo.foo.attr == 'bar'
         assert Foo.foo.method1() == 'method1'
         assert Foo.foo['bar'] == 'value'
-    
+
     def test_comparator(self):
         class Comparator(PropComparator):
             __hash__ = None
-            
+
             attr = 'bar'
-            
+
             def method1(self):
                 return "method1"
-                
+
             def method2(self, other):
                 return "method2"
 
@@ -104,7 +104,7 @@ class DescriptorInstrumentationTest(_base.ORMTest):
             (Foo.foo == 'bar').__str__(),
             "foo = upper(:upper_1)"
         )
-        
+
 
     def test_aliased_comparator(self):
         class Comparator(ColumnProperty.Comparator):
@@ -115,14 +115,14 @@ class DescriptorInstrumentationTest(_base.ORMTest):
 
         Foo = self._fixture()
         Foo._name = Column('name', String)
-        
+
         def comparator_factory(self, mapper):
             prop = mapper._props['_name']
             return Comparator(prop, mapper)
-        
+
         d = TestDescriptor(Foo, 'foo', comparator_factory=comparator_factory)
         d.instrument_class(Foo.__mapper__)
-        
+
         eq_(
             str(Foo.foo == 'ed'),
            "foobar(foo.name) = foobar(:foobar_1)"
index 0958d60dd3dd1138831ae8a8d6663251148a2fb4..ff157407a50beb034612afac24055c643e77cce5 100644 (file)
@@ -20,7 +20,7 @@ class DynamicTest(_fixtures.FixtureTest, AssertsCompiledSQL):
         q = sess.query(User)
 
         u = q.filter(User.id==7).first()
-        
+
         eq_([User(id=7,
                   addresses=[Address(id=1, email_address='jack@bean.com')])],
             q.filter(User.id==7).all())
@@ -30,7 +30,7 @@ class DynamicTest(_fixtures.FixtureTest, AssertsCompiledSQL):
     def test_statement(self):
         """test that the .statement accessor returns the actual statement that
         would render, without any _clones called."""
-        
+
         mapper(User, users, properties={
             'addresses':dynamic_loader(mapper(Address, addresses))
         })
@@ -44,7 +44,7 @@ class DynamicTest(_fixtures.FixtureTest, AssertsCompiledSQL):
             "addresses WHERE :param_1 = addresses.user_id",
             use_default_dialect=True
         )
-        
+
     @testing.resolve_artifact_names
     def test_order_by(self):
         mapper(User, users, properties={
@@ -133,7 +133,7 @@ class DynamicTest(_fixtures.FixtureTest, AssertsCompiledSQL):
             "Dynamic attributes don't support collection population.",
             attributes.set_committed_value, u1, 'addresses', []
         )
-        
+
     @testing.resolve_artifact_names
     def test_m2m(self):
         mapper(Order, orders, properties={
@@ -178,8 +178,8 @@ class DynamicTest(_fixtures.FixtureTest, AssertsCompiledSQL):
             o.items.filter(order_items.c.item_id==2).all(),
             [Item(id=2)]
         )
-        
-        
+
+
     @testing.resolve_artifact_names
     def test_transient_detached(self):
         mapper(User, users, properties={
index e3d14fede4de585edc643e33a60498718e2c2328..095254b2787e7a7fc297d293f2ea1b9a5f7cd9a1 100644 (file)
@@ -39,7 +39,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
         sess = create_session()
         sess.query(User).all()
         m.add_property("addresses", relationship(mapper(Address, addresses)))
-        
+
         sess.expunge_all()
         def go():
             eq_(
@@ -47,12 +47,12 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                sess.query(User).options(joinedload('addresses')).filter(User.id==7).all()
             )
         self.assert_sql_count(testing.db, go, 1)
-            
-        
+
+
     @testing.resolve_artifact_names
     def test_no_orphan(self):
         """An eagerly loaded child object is not marked as an orphan"""
-        
+
         mapper(User, users, properties={
             'addresses':relationship(Address, cascade="all,delete-orphan", lazy='joined')
         })
@@ -114,7 +114,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
     def test_orderby_related(self):
         """A regular mapper select on a single table can 
             order by a relationship to a second table"""
-            
+
         mapper(Address, addresses)
         mapper(User, users, properties = dict(
             addresses = relationship(Address, lazy='joined', order_by=addresses.c.id),
@@ -290,7 +290,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
     @testing.resolve_artifact_names
     def test_disable_dynamic(self):
         """test no joined option on a dynamic."""
-        
+
         mapper(User, users, properties={
             'addresses':relationship(Address, lazy="dynamic")
         })
@@ -368,10 +368,10 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
 
         mapper(Address, addresses)
         mapper(Order, orders)
-        
+
         open_mapper = mapper(Order, openorders, non_primary=True)
         closed_mapper = mapper(Order, closedorders, non_primary=True)
-        
+
         mapper(User, users, properties = dict(
             addresses = relationship(Address, lazy='joined', order_by=addresses.c.id),
             open_orders = relationship(
@@ -628,12 +628,12 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
     def test_useget_cancels_eager(self):
         """test that a one to many lazyload cancels the unnecessary
         eager many-to-one join on the other side."""
-        
+
         mapper(User, users)
         mapper(Address, addresses, properties={
             'user':relationship(User, lazy='joined', backref='addresses')
         })
-        
+
         sess = create_session()
         u1 = sess.query(User).filter(User.id==8).one()
         def go():
@@ -646,13 +646,13 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                 "addresses.user_id",
              {'param_1': 8})
         )
-    
-    
+
+
     @testing.resolve_artifact_names
     def test_manytoone_limit(self):
         """test that the subquery wrapping only occurs with 
         limit/offset and m2m or o2m joins present."""
-        
+
         mapper(User, users, properties=odict(
             orders=relationship(Order, backref='user')
         ))
@@ -662,7 +662,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
         ))
         mapper(Address, addresses)
         mapper(Item, items)
-        
+
         sess = create_session()
 
         self.assert_compile(
@@ -740,7 +740,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             {'param_1':10},
             use_default_dialect=True
         )
-        
+
         self.assert_compile(
             sess.query(User).options(joinedload("orders", innerjoin=True), 
                                         joinedload("orders.address", innerjoin=True)).limit(10),
@@ -756,7 +756,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             {'param_1':10},
             use_default_dialect=True
         )
-        
+
     @testing.resolve_artifact_names
     def test_one_to_many_scalar(self):
         mapper(User, users, properties = dict(
@@ -790,9 +790,9 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
     def test_many_to_one_null(self):
         """test that a many-to-one eager load which loads None does
         not later trigger a lazy load.
-        
+
         """
-        
+
         # use a primaryjoin intended to defeat SA's usage of 
         # query.get() for a many-to-one lazyload
         mapper(Order, orders, properties = dict(
@@ -801,7 +801,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                     addresses.c.id==orders.c.address_id,
                     addresses.c.email_address != None
                 ),
-            
+
             lazy='joined')
         ))
         sess = create_session()
@@ -810,13 +810,13 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             o1 = sess.query(Order).options(lazyload('address')).filter(Order.id==5).one()
             eq_(o1.address, None)
         self.assert_sql_count(testing.db, go, 2)
-        
+
         sess.expunge_all()
         def go():
             o1 = sess.query(Order).filter(Order.id==5).one()
             eq_(o1.address, None)
         self.assert_sql_count(testing.db, go, 1)
-        
+
     @testing.resolve_artifact_names
     def test_one_and_many(self):
         """tests eager load for a parent object with a child object that
@@ -879,7 +879,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
     def test_uselist_false_warning(self):
         """test that multiple rows received by a 
         uselist=False raises a warning."""
-        
+
         mapper(User, users, properties={
             'order':relationship(Order, uselist=False)
         })
@@ -887,7 +887,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
         s = create_session()
         assert_raises(sa.exc.SAWarning,
                 s.query(User).options(joinedload(User.order)).all)
-        
+
     @testing.resolve_artifact_names
     def test_wide(self):
         mapper(Order, orders, properties={'items':relationship(Item, secondary=order_items, lazy='joined',
@@ -972,7 +972,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                                     innerjoin=True)
         ))
         mapper(Item, items)
-        
+
         sess = create_session()
         self.assert_compile(
             sess.query(User),
@@ -986,7 +986,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             "order_items_1.item_id",
             use_default_dialect=True
         )
-        
+
         self.assert_compile(
             sess.query(User).options(joinedload(User.orders, innerjoin=False)),
             "SELECT users.id AS users_id, users.name AS users_name, items_1.id AS "
@@ -1012,7 +1012,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             "order_items_1.item_id",
             use_default_dialect=True
         )
-        
+
     @testing.resolve_artifact_names
     def test_inner_join_chaining_fixed(self):
         mapper(User, users, properties = dict(
@@ -1023,7 +1023,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                                     innerjoin=True)
         ))
         mapper(Item, items)
-        
+
         sess = create_session()
 
         # joining from user, its all LEFT OUTER JOINs
@@ -1039,7 +1039,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             "order_items_1.item_id",
             use_default_dialect=True
         )
-        
+
         # joining just from Order, innerjoin=True can be respected
         self.assert_compile(
             sess.query(Order),
@@ -1052,8 +1052,8 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             "order_items_1.item_id",
             use_default_dialect=True
         )
-        
-        
+
+
 
     @testing.resolve_artifact_names
     def test_inner_join_options(self):
@@ -1081,14 +1081,14 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             "order_items_1 ON orders_1.id = order_items_1.order_id JOIN items AS items_1 ON "
             "items_1.id = order_items_1.item_id ORDER BY orders_1.id, items_1.id"
         , use_default_dialect=True)
-        
+
         def go():
             eq_(
                 sess.query(User).options(
                     joinedload(User.orders, innerjoin=True), 
                     joinedload(User.orders, Order.items, innerjoin=True)).
                     order_by(User.id).all(),
-                    
+
                 [User(id=7, 
                     orders=[ 
                         Order(id=1, items=[ Item(id=1), Item(id=2), Item(id=3)]), 
@@ -1100,7 +1100,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                 ]
             )
         self.assert_sql_count(testing.db, go, 1)
-        
+
         # test that default innerjoin setting is used for options
         self.assert_compile(
             sess.query(Order).options(joinedload(Order.user)).filter(Order.description == 'foo'),
@@ -1111,7 +1111,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             "WHERE orders.description = :description_1",
             use_default_dialect=True
         )
-        
+
 class AddEntityTest(_fixtures.FixtureTest):
     run_inserts = 'once'
     run_deletes = None
@@ -1511,7 +1511,7 @@ class MixedSelfReferentialEagerTest(_base.MappedTest):
             pass
         class B(_base.ComparableEntity):
             pass
-            
+
         mapper(A,a_table)
         mapper(B,b_table,properties = {
            'parent_b1': relationship(B,
@@ -1526,7 +1526,7 @@ class MixedSelfReferentialEagerTest(_base.MappedTest):
                             order_by = b_table.c.id
                             )
         });
-    
+
     @classmethod
     @testing.resolve_artifact_names
     def insert_data(cls):
@@ -1547,7 +1547,7 @@ class MixedSelfReferentialEagerTest(_base.MappedTest):
             dict(id=13, parent_a_id=3, parent_b1_id=4, parent_b2_id=4),
             dict(id=14, parent_a_id=3, parent_b1_id=7, parent_b2_id=2),
         )
-        
+
     @testing.resolve_artifact_names
     def test_eager_load(self):
         session = create_session()
@@ -1566,7 +1566,7 @@ class MixedSelfReferentialEagerTest(_base.MappedTest):
                 ]
             )
         self.assert_sql_count(testing.db, go, 1)
-        
+
 class SelfReferentialM2MEagerTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -1659,7 +1659,7 @@ class MixedEntitiesTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
     @testing.resolve_artifact_names
     def test_two_entities_with_joins(self):
         sess = create_session()
-        
+
         # two FROM clauses where there's a join on each one
         def go():
             u1 = aliased(User)
@@ -1694,8 +1694,8 @@ class MixedEntitiesTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                         order_by(User.id, Order.id, u1.id, o1.id).all(),
             )
         self.assert_sql_count(testing.db, go, 1)
-        
-        
+
+
 
     @testing.resolve_artifact_names
     def test_aliased_entity(self):
@@ -1871,18 +1871,18 @@ class SubqueryTest(_base.MappedTest):
 
 class CorrelatedSubqueryTest(_base.MappedTest):
     """tests for #946, #947, #948.
-    
+
     The "users" table is joined to "stuff", and the relationship
     would like to pull only the "stuff" entry with the most recent date.
-    
+
     Exercises a variety of ways to configure this.
-    
+
     """
 
     # another argument for joinedload learning about inner joins
-    
+
     __requires__ = ('correlated_outer_joins', )
-    
+
     @classmethod
     def define_tables(cls, metadata):
         users = Table('users', metadata,
@@ -1894,7 +1894,7 @@ class CorrelatedSubqueryTest(_base.MappedTest):
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('date', Date),
             Column('user_id', Integer, ForeignKey('users.id')))
-    
+
     @classmethod
     @testing.resolve_artifact_names
     def insert_data(cls):
@@ -1912,8 +1912,8 @@ class CorrelatedSubqueryTest(_base.MappedTest):
             {'id':5, 'user_id':3, 'date':datetime.date(2007, 6, 15)},
             {'id':6, 'user_id':3, 'date':datetime.date(2007, 3, 15)},
         )
-        
-    
+
+
     def test_labeled_on_date_noalias(self):
         self._do_test('label', True, False)
 
@@ -1949,7 +1949,7 @@ class CorrelatedSubqueryTest(_base.MappedTest):
 
     def test_plain_on_limitid_alias(self):
         self._do_test('none', False, True)
-        
+
     @testing.resolve_artifact_names
     def _do_test(self, labeled, ondate, aliasstuff):
         class User(_base.ComparableEntity):
@@ -1957,7 +1957,7 @@ class CorrelatedSubqueryTest(_base.MappedTest):
 
         class Stuff(_base.ComparableEntity):
             pass
-        
+
         mapper(Stuff, stuff)
 
         if aliasstuff:
@@ -1991,7 +1991,7 @@ class CorrelatedSubqueryTest(_base.MappedTest):
             mapper(User, users, properties={
                 'stuff':relationship(Stuff, primaryjoin=and_(users.c.id==stuff.c.user_id, stuff.c.id==stuff_view))
             })
-            
+
         sess = create_session()
         def go():
             eq_(
@@ -2003,7 +2003,7 @@ class CorrelatedSubqueryTest(_base.MappedTest):
                 ]
             )
         self.assert_sql_count(testing.db, go, 1)
-    
+
         sess = create_session()
         def go():
             eq_(
index 26f9f49c3e3105aadda4f4a80d5d453912085d65..017619cfe97254cca0748dba7eb1e7cbc96c9d94 100644 (file)
@@ -27,17 +27,17 @@ class EvaluateTest(_base.MappedTest):
         Table('users', metadata,
               Column('id', Integer, primary_key=True),
               Column('name', String(64)))
-    
+
     @classmethod
     def setup_classes(cls):
         class User(_base.ComparableEntity):
             pass
-    
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_mappers(cls):
         mapper(User, users)
-    
+
     @testing.resolve_artifact_names
     def test_compare_to_value(self):
         eval_eq(User.name == 'foo', testcases=[
@@ -45,20 +45,20 @@ class EvaluateTest(_base.MappedTest):
             (User(name='bar'), False),
             (User(name=None), None),
         ])
-        
+
         eval_eq(User.id < 5, testcases=[
             (User(id=3), True),
             (User(id=5), False),
             (User(id=None), None),
         ])
-    
+
     @testing.resolve_artifact_names
     def test_compare_to_none(self):
         eval_eq(User.name == None, testcases=[
             (User(name='foo'), False),
             (User(name=None), True),
         ])
-   
+
     @testing.resolve_artifact_names
     def test_boolean_ops(self):
         eval_eq(and_(User.name == 'foo', User.id == 1), testcases=[
@@ -68,7 +68,7 @@ class EvaluateTest(_base.MappedTest):
             (User(id=2, name='bar'), False),
             (User(id=1, name=None), None),
         ])
-        
+
         eval_eq(or_(User.name == 'foo', User.id == 1), testcases=[
             (User(id=1, name='foo'), True),
             (User(id=2, name='foo'), True),
@@ -77,7 +77,7 @@ class EvaluateTest(_base.MappedTest):
             (User(id=1, name=None), True),
             (User(id=2, name=None), None),
         ])
-        
+
         eval_eq(not_(User.id == 1), testcases=[
             (User(id=1), False),
             (User(id=2), True),
index b2900c93fb6765b2a7fb712497e7035317683767..25f94e487a9127cd6f16b1f8d6c82d1c8ba347ff 100644 (file)
@@ -21,27 +21,27 @@ class _RemoveListeners(object):
         ClassManager.dispatch._clear()
         Session.dispatch._clear()
         super(_RemoveListeners, self).teardown()
-    
+
 
 class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest):
     run_inserts = None
-    
+
     @testing.resolve_artifact_names
     def test_instance_event_listen(self):
         """test listen targets for instance events"""
-        
+
         canary = []
         class A(object):
             pass
         class B(A):
             pass
-            
+
         mapper(A, users)
         mapper(B, addresses, inherits=A)
-        
+
         def init_a(target, args, kwargs):
             canary.append(('init_a', target))
-            
+
         def init_b(target, args, kwargs):
             canary.append(('init_b', target))
 
@@ -53,30 +53,30 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest):
 
         def init_e(target, args, kwargs):
             canary.append(('init_e', target))
-        
+
         event.listen(mapper, 'init', init_a)
         event.listen(Mapper, 'init', init_b)
         event.listen(class_mapper(A), 'init', init_c)
         event.listen(A, 'init', init_d)
         event.listen(A, 'init', init_e, propagate=True)
-        
+
         a = A()
         eq_(canary, [('init_a', a),('init_b', a),
                         ('init_c', a),('init_d', a),('init_e', a)])
-        
+
         # test propagate flag
         canary[:] = []
         b = B()
         eq_(canary, [('init_a', b), ('init_b', b),('init_e', b)])
-    
-        
+
+
     def listen_all(self, mapper, **kw):
         canary = []
         def evt(meth):
             def go(*args, **kwargs):
                 canary.append(meth)
             return go
-            
+
         for meth in [
             'init',
             'init_failure',
@@ -102,7 +102,7 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest):
 
         mapper(User, users)
         canary = self.listen_all(User)
-        
+
         sess = create_session()
         u = User(name='u1')
         sess.add(u)
@@ -164,16 +164,16 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest):
     def test_before_after_only_collection(self):
         """before_update is called on parent for collection modifications,
         after_update is called even if no columns were updated.
-        
+
         """
 
         mapper(Item, items, properties={
             'keywords': relationship(Keyword, secondary=item_keywords)})
         mapper(Keyword, keywords)
-        
+
         canary1 = self.listen_all(Item)
         canary2 = self.listen_all(Keyword)
-        
+
         sess = create_session()
         i1 = Item(description="i1")
         k1 = Keyword(name="k1")
@@ -195,14 +195,14 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest):
         eq_(canary1, ['before_update', 'after_update'])
         eq_(canary2, [])
 
-        
+
     @testing.resolve_artifact_names
     def test_retval(self):
         def create_instance(mapper, context, row, class_):
             u = User.__new__(User)
             u.foo = True
             return u
-            
+
         mapper(User, users)
         event.listen(User, 'create_instance', create_instance, retval=True)
         sess = create_session()
@@ -213,20 +213,20 @@ class MapperEventsTest(_RemoveListeners, _fixtures.FixtureTest):
         sess.expunge_all()
         u = sess.query(User).first()
         assert u.foo
-    
+
     @testing.resolve_artifact_names
     def test_instrument_event(self):
         canary = []
         def instrument_class(mapper, cls):
             canary.append(cls)
-            
+
         event.listen(Mapper, 'instrument_class', instrument_class)
-        
+
         mapper(User, users)
         eq_(canary, [User])
         mapper(Address, addresses)
         eq_(canary, [User, Address])
-    
+
 
 class LoadTest(_fixtures.FixtureTest):
     run_inserts = None
@@ -235,7 +235,7 @@ class LoadTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def setup_mappers(cls):
         mapper(User, users)
-    
+
     @testing.resolve_artifact_names
     def _fixture(self):
         canary = []
@@ -243,7 +243,7 @@ class LoadTest(_fixtures.FixtureTest):
             canary.append("load")
         def refresh(target, ctx, attrs):
             canary.append(("refresh", attrs))
-        
+
         event.listen(User, "load", load)
         event.listen(User, "refresh", refresh)
         return canary
@@ -251,33 +251,33 @@ class LoadTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_just_loaded(self):
         canary = self._fixture()
-        
+
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
         sess.commit()
         sess.close()
-        
+
         sess.query(User).first()
         eq_(canary, ['load'])
 
     @testing.resolve_artifact_names
     def test_repeated_rows(self):
         canary = self._fixture()
-        
+
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
         sess.commit()
         sess.close()
-        
+
         sess.query(User).union_all(sess.query(User)).all()
         eq_(canary, ['load'])
-    
-    
-    
+
+
+
 class RefreshTest(_fixtures.FixtureTest):
     run_inserts = None
 
@@ -285,7 +285,7 @@ class RefreshTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def setup_mappers(cls):
         mapper(User, users)
-    
+
     @testing.resolve_artifact_names
     def _fixture(self):
         canary = []
@@ -293,7 +293,7 @@ class RefreshTest(_fixtures.FixtureTest):
             canary.append("load")
         def refresh(target, ctx, attrs):
             canary.append(("refresh", attrs))
-        
+
         event.listen(User, "load", load)
         event.listen(User, "refresh", refresh)
         return canary
@@ -301,96 +301,96 @@ class RefreshTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_already_present(self):
         canary = self._fixture()
-        
+
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
         sess.flush()
-        
+
         sess.query(User).first()
         eq_(canary, [])
 
     @testing.resolve_artifact_names
     def test_repeated_rows(self):
         canary = self._fixture()
-        
+
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
         sess.commit()
-        
+
         sess.query(User).union_all(sess.query(User)).all()
         eq_(canary, [('refresh', set(['id','name']))])
 
     @testing.resolve_artifact_names
     def test_via_refresh_state(self):
         canary = self._fixture()
-        
+
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
         sess.commit()
-        
+
         u1.name
         eq_(canary, [('refresh', set(['id','name']))])
 
     @testing.resolve_artifact_names
     def test_was_expired(self):
         canary = self._fixture()
-        
+
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
         sess.flush()
         sess.expire(u1)
-        
+
         sess.query(User).first()
         eq_(canary, [('refresh', set(['id','name']))])
 
     @testing.resolve_artifact_names
     def test_was_expired_via_commit(self):
         canary = self._fixture()
-        
+
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
         sess.commit()
-        
+
         sess.query(User).first()
         eq_(canary, [('refresh', set(['id','name']))])
 
     @testing.resolve_artifact_names
     def test_was_expired_attrs(self):
         canary = self._fixture()
-        
+
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
         sess.flush()
         sess.expire(u1, ['name'])
-        
+
         sess.query(User).first()
         eq_(canary, [('refresh', set(['name']))])
-        
+
     @testing.resolve_artifact_names
     def test_populate_existing(self):
         canary = self._fixture()
-        
+
         sess = Session()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
         sess.commit()
-        
+
         sess.query(User).populate_existing().first()
         eq_(canary, [('refresh', None)])
-    
+
 
 class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
     run_inserts = None
@@ -398,42 +398,42 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
     def test_class_listen(self):
         def my_listener(*arg, **kw):
             pass
-        
+
         event.listen(Session, 'before_flush', my_listener)
-        
+
         s = Session()
         assert my_listener in s.dispatch.before_flush
-    
+
     def test_sessionmaker_listen(self):
         """test that listen can be applied to individual scoped_session() classes."""
-        
+
         def my_listener_one(*arg, **kw):
             pass
         def my_listener_two(*arg, **kw):
             pass
-        
+
         S1 = sessionmaker()
         S2 = sessionmaker()
-        
+
         event.listen(Session, 'before_flush', my_listener_one)
         event.listen(S1, 'before_flush', my_listener_two)
-        
+
         s1 = S1()
         assert my_listener_one in s1.dispatch.before_flush
         assert my_listener_two in s1.dispatch.before_flush
-        
+
         s2 = S2()
         assert my_listener_one in s2.dispatch.before_flush
         assert my_listener_two not in s2.dispatch.before_flush
-    
+
     def test_scoped_session_invalid_callable(self):
         from sqlalchemy.orm import scoped_session
-        
+
         def my_listener_one(*arg, **kw):
             pass
-        
+
         scope = scoped_session(lambda:Session())
-        
+
         assert_raises_message(
             sa.exc.ArgumentError,
             "Session event listen on a ScopedSession "
@@ -443,41 +443,41 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
 
     def test_scoped_session_invalid_class(self):
         from sqlalchemy.orm import scoped_session
-        
+
         def my_listener_one(*arg, **kw):
             pass
-        
+
         class NotASession(object):
             def __call__(self):
                 return Session()
-                
+
         scope = scoped_session(NotASession)
-        
+
         assert_raises_message(
             sa.exc.ArgumentError,
             "Session event listen on a ScopedSession "
             "requries that its creation callable is a Session subclass.",
             event.listen, scope, "before_flush", my_listener_one
         )
-    
+
     def test_scoped_session_listen(self):
         from sqlalchemy.orm import scoped_session
-        
+
         def my_listener_one(*arg, **kw):
             pass
-        
+
         scope = scoped_session(sessionmaker())
         event.listen(scope, "before_flush", my_listener_one)
-        
+
         assert my_listener_one in scope().dispatch.before_flush
-    
+
     def _listener_fixture(self, **kw):
         canary = []
         def listener(name):
             def go(*arg, **kw):
                 canary.append(name)
             return go
-        
+
         sess = Session(**kw)
 
         for evt in [
@@ -493,16 +493,16 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
             'after_bulk_delete'
         ]:
             event.listen(sess, evt, listener(evt))
-        
+
         return sess, canary
-        
+
     @testing.resolve_artifact_names
     def test_flush_autocommit_hook(self):
-        
+
         mapper(User, users)
 
         sess, canary = self._listener_fixture(autoflush=False, autocommit=True)
-        
+
         u = User(name='u1')
         sess.add(u)
         sess.flush()
@@ -524,7 +524,7 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
         sess.flush()
         eq_(canary, ['after_attach', 'before_flush', 'after_begin',
                        'after_flush', 'after_flush_postexec'])
-    
+
     @testing.resolve_artifact_names
     def test_flush_in_commit_hook(self):
         sess, canary = self._listener_fixture()
@@ -534,17 +534,17 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
         sess.add(u)
         sess.flush()
         canary[:] = []
-        
+
         u.name = 'ed'
         sess.commit()
         eq_(canary, ['before_commit', 'before_flush', 'after_flush',
                        'after_flush_postexec', 'after_commit'])
-    
+
     def test_standalone_on_commit_hook(self):
         sess, canary = self._listener_fixture()
         sess.commit()
         eq_(canary, ['before_commit', 'after_commit'])
-        
+
     @testing.resolve_artifact_names
     def test_on_bulk_update_hook(self):
         sess, canary = self._listener_fixture()
@@ -558,7 +558,7 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
         mapper(User, users)
         sess.query(User).delete()
         eq_(canary, ['after_begin', 'after_bulk_delete'])
-    
+
     def test_connection_emits_after_begin(self):
         sess, canary = self._listener_fixture(bind=testing.db)
         conn = sess.connection()
@@ -571,7 +571,7 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
 
         def before_flush(session, flush_context, objects):
             session.flush()
-        
+
         sess = Session()
         event.listen(sess, 'before_flush', before_flush)
         sess.add(User(name='foo'))
@@ -580,9 +580,9 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
 
     @testing.resolve_artifact_names
     def test_before_flush_affects_flush_plan(self):
-        
+
         mapper(User, users)
-        
+
         def before_flush(session, flush_context, objects):
             for obj in list(session.new) + list(session.dirty):
                 if isinstance(obj, User):
@@ -592,7 +592,7 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
                     x = session.query(User).filter(User.name
                             == 'another %s' % obj.name).one()
                     session.delete(x)
-                    
+
         sess = Session()
         event.listen(sess, 'before_flush', before_flush)
 
@@ -605,7 +605,7 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
                 User(name='u1')
             ]
         )
-        
+
         sess.flush()
         eq_(sess.query(User).order_by(User.name).all(), 
             [
@@ -635,21 +635,21 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_before_flush_affects_dirty(self):
         mapper(User, users)
-        
+
         def before_flush(session, flush_context, objects):
             for obj in list(session.identity_map.values()):
                 obj.name += " modified"
-                    
+
         sess = Session(autoflush=True)
         event.listen(sess, 'before_flush', before_flush)
-        
+
         u = User(name='u1')
         sess.add(u)
         sess.flush()
         eq_(sess.query(User).order_by(User.name).all(), 
             [User(name='u1')]
         )
-        
+
         sess.add(User(name='u2'))
         sess.flush()
         sess.expunge_all()
@@ -659,15 +659,15 @@ class SessionEventsTest(_RemoveListeners, _fixtures.FixtureTest):
                 User(name='u2')
             ]
         )
-        
 
-        
+
+
 class MapperExtensionTest(_fixtures.FixtureTest):
     """Superceded by MapperEventsTest - test backwards 
     compatiblity of MapperExtension."""
-    
+
     run_inserts = None
-    
+
     def extension(self):
         methods = []
 
@@ -787,7 +787,7 @@ class MapperExtensionTest(_fixtures.FixtureTest):
     def test_before_after_only_collection(self):
         """before_update is called on parent for collection modifications,
         after_update is called even if no columns were updated.
-        
+
         """
 
         Ext1, methods1 = self.extension()
@@ -848,13 +848,13 @@ class MapperExtensionTest(_fixtures.FixtureTest):
              'create_instance', 'populate_instance', 'reconstruct_instance',
              'append_result', 'before_update', 'after_update', 'before_delete',
              'after_delete'])
-        
+
     @testing.resolve_artifact_names
     def test_create_instance(self):
         class CreateUserExt(sa.orm.MapperExtension):
             def create_instance(self, mapper, selectcontext, row, class_):
                 return User.__new__(User)
-                
+
         mapper(User, users, extension=CreateUserExt())
         sess = create_session()
         u1 = User()
@@ -873,30 +873,30 @@ class AttributeExtensionTest(_base.MappedTest):
             Column('id', Integer, primary_key=True),
             Column('type', String(40)),
             Column('data', String(50))
-            
+
         )
 
     @testing.resolve_artifact_names
     def test_cascading_extensions(self):
         ext_msg = []
-        
+
         class Ex1(sa.orm.AttributeExtension):
             def set(self, state, value, oldvalue, initiator):
                 ext_msg.append("Ex1 %r" % value)
                 return "ex1" + value
-                
+
         class Ex2(sa.orm.AttributeExtension):
             def set(self, state, value, oldvalue, initiator):
                 ext_msg.append("Ex2 %r" % value)
                 return "ex2" + value
-        
+
         class A(_base.BasicEntity):
             pass
         class B(A):
             pass
         class C(B):
             pass
-            
+
         mapper(A, t1, polymorphic_on=t1.c.type, polymorphic_identity='a', properties={
             'data':column_property(t1.c.data, extension=Ex1())
         })
@@ -904,26 +904,26 @@ class AttributeExtensionTest(_base.MappedTest):
         mc = mapper(C, polymorphic_identity='c', inherits=B, properties={
             'data':column_property(t1.c.data, extension=Ex2())
         })
-        
+
         a1 = A(data='a1')
         b1 = B(data='b1')
         c1 = C(data='c1')
-        
+
         eq_(a1.data, 'ex1a1')
         eq_(b1.data, 'ex1b1')
         eq_(c1.data, 'ex2c1')
-        
+
         a1.data = 'a2'
         b1.data='b2'
         c1.data = 'c2'
         eq_(a1.data, 'ex1a2')
         eq_(b1.data, 'ex1b2')
         eq_(c1.data, 'ex2c2')
-        
+
         eq_(ext_msg, ["Ex1 'a1'", "Ex1 'b1'", "Ex2 'c1'", 
                     "Ex1 'a2'", "Ex1 'b2'", "Ex2 'c2'"])
 
-        
+
 
 class SessionExtensionTest(_fixtures.FixtureTest):
     run_inserts = None
@@ -1013,7 +1013,7 @@ class SessionExtensionTest(_fixtures.FixtureTest):
         class MyExt1(sa.orm.session.SessionExtension):
             def before_commit(self, session):
                 log.append('before_commit_one')
-        
+
 
         class MyExt2(sa.orm.session.SessionExtension):
             def before_commit(self, session):
@@ -1028,4 +1028,4 @@ class SessionExtensionTest(_fixtures.FixtureTest):
             'before_commit_one',
             'before_commit_two',
             ]
-        
+
index d691e7270c5a85b4aa6c9454edf9b23de9a079a7..68b254725abd3fd3770d38be862a367944c9ccde 100644 (file)
@@ -92,7 +92,7 @@ class ExpireTest(_fixtures.FixtureTest):
         # trick the "deleted" flag so we can re-add for the sake
         # of this test
         del attributes.instance_state(u).deleted
-        
+
         # add it back
         s.add(u)
         # nope, raises ObjectDeletedError
@@ -101,7 +101,7 @@ class ExpireTest(_fixtures.FixtureTest):
         # do a get()/remove u from session again
         assert s.query(User).get(10) is None
         assert u not in s
-        
+
         s.rollback()
 
         assert u in s
@@ -112,9 +112,9 @@ class ExpireTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_deferred(self):
         """test that unloaded, deferred attributes aren't included in the expiry list."""
-        
+
         mapper(Order, orders, properties={'description':deferred(orders.c.description)})
-        
+
         s = create_session()
         o1 = s.query(Order).first()
         assert 'description' not in o1.__dict__
@@ -122,7 +122,7 @@ class ExpireTest(_fixtures.FixtureTest):
         assert o1.isopen is not None
         assert 'description' not in o1.__dict__
         assert o1.description
-        
+
     @testing.resolve_artifact_names
     def test_lazyload_autoflushes(self):
         mapper(User, users, properties={
@@ -150,7 +150,7 @@ class ExpireTest(_fixtures.FixtureTest):
     def test_refresh_collection_exception(self):
         """test graceful failure for currently unsupported 
         immediate refresh of a collection"""
-        
+
         mapper(User, users, properties={
             'addresses':relationship(Address, order_by=addresses.c.email_address)
         })
@@ -160,11 +160,11 @@ class ExpireTest(_fixtures.FixtureTest):
         assert_raises_message(sa_exc.InvalidRequestError, 
                         "properties specified for refresh", 
                         s.refresh, u, ['addresses'])
-        
+
         # in contrast to a regular query with no columns
         assert_raises_message(sa_exc.InvalidRequestError, 
                         "no columns with which to SELECT", s.query().all)
-        
+
     @testing.resolve_artifact_names
     def test_refresh_cancels_expire(self):
         mapper(User, users)
@@ -229,7 +229,7 @@ class ExpireTest(_fixtures.FixtureTest):
         assert 'name' not in u.__dict__
         sess.add(u)
         assert u.name == 'jack'
-    
+
     @testing.resolve_artifact_names
     def test_no_instance_key_no_pk(self):
         # same as test_no_instance_key, but the PK columns
@@ -245,7 +245,7 @@ class ExpireTest(_fixtures.FixtureTest):
         sess.add(u)
         assert_raises(sa_exc.InvalidRequestError, getattr, u, 'name')
 
-        
+
     @testing.resolve_artifact_names
     def test_expire_preserves_changes(self):
         """test that the expire load operation doesn't revert post-expire changes"""
@@ -350,7 +350,7 @@ class ExpireTest(_fixtures.FixtureTest):
     def test_refresh_cascade_pending(self):
         cascade = 'save-update, refresh-expire'
         self._test_cascade_to_pending(cascade, False)
-        
+
     @testing.resolve_artifact_names
     def _test_cascade_to_pending(self, cascade, expire_or_refresh):
         mapper(User, users, properties={
@@ -361,7 +361,7 @@ class ExpireTest(_fixtures.FixtureTest):
 
         u = s.query(User).get(8)
         a = Address(id=12, email_address='foobar')
-        
+
         u.addresses.append(a)
         if expire_or_refresh:
             s.expire(u)
@@ -371,7 +371,7 @@ class ExpireTest(_fixtures.FixtureTest):
             assert a not in s
         else:
             assert a in s
-        
+
         assert a not in u.addresses
         s.flush()
 
@@ -759,9 +759,9 @@ class ExpireTest(_fixtures.FixtureTest):
         """Behavioral test to verify the current activity of loader callables."""
 
         mapper(User, users)
-        
+
         sess = create_session()
-        
+
         # deferred attribute option, gets the LoadDeferredColumns
         # callable
         u1 = sess.query(User).options(defer(User.name)).first()
@@ -769,14 +769,14 @@ class ExpireTest(_fixtures.FixtureTest):
                     attributes.instance_state(u1).callables['name'],
                     strategies.LoadDeferredColumns
                 )
-                
+
         # expire the attr, it gets the InstanceState callable
         sess.expire(u1, ['name'])
         assert isinstance(
                     attributes.instance_state(u1).callables['name'],
                     state.InstanceState
                 )
-                
+
         # load it, callable is gone
         u1.name
         assert 'name' not in attributes.instance_state(u1).callables
@@ -789,28 +789,28 @@ class ExpireTest(_fixtures.FixtureTest):
                     attributes.instance_state(u1).callables['name'],
                     state.InstanceState
                 )
-        
+
         # load over it.  everything normal.
         sess.query(User).first()
         assert 'name' not in attributes.instance_state(u1).callables
-        
+
         sess.expunge_all()
         u1 = sess.query(User).first()
         # for non present, still expires the same way
         del u1.name
         sess.expire(u1)
         assert 'name' in attributes.instance_state(u1).callables
-        
+
     @testing.resolve_artifact_names
     def test_state_deferred_to_col(self):
         """Behavioral test to verify the current activity of loader callables."""
-        
+
         mapper(User, users, properties={'name':deferred(users.c.name)})
 
         sess = create_session()
         u1 = sess.query(User).options(undefer(User.name)).first()
         assert 'name' not in attributes.instance_state(u1).callables
-        
+
         # mass expire, the attribute was loaded, 
         # the attribute gets the callable
         sess.expire(u1)
@@ -822,7 +822,7 @@ class ExpireTest(_fixtures.FixtureTest):
         # load it, callable is gone
         u1.name
         assert 'name' not in attributes.instance_state(u1).callables
-        
+
         # mass expire, attribute was loaded but then deleted,
         # the callable goes away - the state wants to flip 
         # it back to its "deferred" loader.
@@ -847,7 +847,7 @@ class ExpireTest(_fixtures.FixtureTest):
 
         mapper(User, users, properties={'addresses':relationship(Address, lazy='noload')})
         mapper(Address, addresses)
-        
+
         sess = create_session()
         u1 = sess.query(User).options(lazyload(User.addresses)).first()
         assert isinstance(
@@ -860,11 +860,11 @@ class ExpireTest(_fixtures.FixtureTest):
                     attributes.instance_state(u1).callables['addresses'],
                     strategies.LoadLazyAttribute
                 )
-        
+
         # load over it.  callable goes away.
         sess.query(User).first()
         assert 'addresses' not in attributes.instance_state(u1).callables
-        
+
         sess.expunge_all()
         u1 = sess.query(User).options(lazyload(User.addresses)).first()
         sess.expire(u1, ['addresses'])
@@ -872,13 +872,13 @@ class ExpireTest(_fixtures.FixtureTest):
                     attributes.instance_state(u1).callables['addresses'],
                     strategies.LoadLazyAttribute
                 )
-        
+
         # load the attr, goes away
         u1.addresses
         assert 'addresses' not in attributes.instance_state(u1).callables
-        
-        
-        
+
+
+
 class PolymorphicExpireTest(_base.MappedTest):
     run_inserts = 'once'
     run_deletes = None
@@ -919,13 +919,13 @@ class PolymorphicExpireTest(_base.MappedTest):
             {'person_id':2, 'status':'new engineer'},
             {'person_id':3, 'status':'old engineer'},
         )
-    
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_mappers(cls):
         mapper(Person, people, polymorphic_on=people.c.type, polymorphic_identity='person')
         mapper(Engineer, engineers, inherits=Person, polymorphic_identity='engineer')
-        
+
     @testing.resolve_artifact_names
     def test_poly_deferred(self):
 
@@ -965,7 +965,7 @@ class PolymorphicExpireTest(_base.MappedTest):
 
     @testing.resolve_artifact_names
     def test_no_instance_key(self):
-        
+
         sess = create_session()
         e1 = sess.query(Engineer).get(2)
 
@@ -975,7 +975,7 @@ class PolymorphicExpireTest(_base.MappedTest):
         assert 'name' not in e1.__dict__
         sess.add(e1)
         assert e1.name == 'engineer1'
-    
+
     @testing.resolve_artifact_names
     def test_no_instance_key(self):
         # same as test_no_instance_key, but the PK columns
@@ -996,7 +996,7 @@ class ExpiredPendingTest(_fixtures.FixtureTest):
     run_setup_classes = 'once'
     run_setup_mappers = None
     run_inserts = None
-    
+
     @testing.resolve_artifact_names
     def test_expired_pending(self):
         mapper(User, users, properties={
@@ -1008,7 +1008,7 @@ class ExpiredPendingTest(_fixtures.FixtureTest):
         a1 = Address(email_address='a1')
         sess.add(a1)
         sess.flush()
-        
+
         u1 = User(name='u1')
         a1.user = u1
         sess.flush()
@@ -1025,17 +1025,17 @@ class ExpiredPendingTest(_fixtures.FixtureTest):
         # expire u1.addresses again.  this expires
         # "pending" as well.
         sess.expire(u1, ['addresses'])
-        
+
         # insert a new row
         sess.execute(addresses.insert(), dict(email_address='a3', user_id=u1.id))
-        
+
         # only two addresses pulled from the DB, no "pending"
         assert len(u1.addresses) == 2
-        
+
         sess.flush()
         sess.expire_all()
         assert len(u1.addresses) == 3
-    
+
 
 class RefreshTest(_fixtures.FixtureTest):
 
index c20cad0da71501ea727aac677c9db3cc1c833519..0cc6a957b7b810c5b7a09a6371c39cdfecfeab9f 100644 (file)
@@ -109,18 +109,18 @@ class UserDefinedExtensionTest(_base.ORMTest):
     def test_instance_dict(self):
         class User(MyClass):
             pass
-            
+
         instrumentation.register_class(User)
         attributes.register_attribute(User, 'user_id', uselist = False, useobject=False)
         attributes.register_attribute(User, 'user_name', uselist = False, useobject=False)
         attributes.register_attribute(User, 'email_address', uselist = False, useobject=False)
-            
+
         u = User()
         u.user_id = 7
         u.user_name = 'john'
         u.email_address = 'lala@123.com'
         self.assert_(u.__dict__ == {'_my_state':u._my_state, '_goofy_dict':{'user_id':7, 'user_name':'john', 'email_address':'lala@123.com'}}, u.__dict__)
-        
+
     def test_basic(self):
         for base in (object, MyBaseClass, MyClass):
             class User(base):
@@ -158,7 +158,7 @@ class UserDefinedExtensionTest(_base.ORMTest):
             manager.deferred_scalar_loader = loader
             attributes.register_attribute(Foo, 'a', uselist=False, useobject=False)
             attributes.register_attribute(Foo, 'b', uselist=False, useobject=False)
-            
+
             assert Foo in instrumentation.instrumentation_registry._state_finders
             f = Foo()
             attributes.instance_state(f).expire(attributes.instance_dict(f), set())
index 6c86fa7ec602a5fd4499ad592ec0d124dc9af6ac..f07ddc7def71e31966ca1c290b7cc41f6c548686 100644 (file)
@@ -62,9 +62,9 @@ class QueryTest(_fixtures.FixtureTest):
 
 class RawSelectTest(QueryTest, AssertsCompiledSQL):
     """compare a bunch of select() tests with the equivalent Query using straight table/columns.
-    
+
     Results should be the same as Query should act as a select() pass-thru for ClauseElement entities.
-    
+
     """
     def test_select(self):
         sess = create_session()
@@ -86,7 +86,7 @@ class RawSelectTest(QueryTest, AssertsCompiledSQL):
         # TODO: can we detect only one table in the "froms" and then turn off use_labels ?
         s = sess.query(addresses.c.id.label('id'), addresses.c.email_address.label('email')).\
             filter(addresses.c.user_id==users.c.id).correlate(users).statement.alias()
-            
+
         self.assert_compile(sess.query(users, s.c.email).select_from(users.join(s, s.c.id==users.c.id)).with_labels().statement, 
                 "SELECT users.id AS users_id, users.name AS users_name, anon_1.email AS anon_1_email "
                 "FROM users JOIN (SELECT addresses.id AS id, addresses.email_address AS email FROM addresses "
@@ -98,7 +98,7 @@ class RawSelectTest(QueryTest, AssertsCompiledSQL):
         self.assert_compile(sess.query(x).filter(x==5).statement, 
             "SELECT lala(users.id) AS foo FROM users WHERE lala(users.id) = :param_1", dialect=default.DefaultDialect())
 
-        self.assert_compile(sess.query(func.sum(x).label('bar')).statement,  
+        self.assert_compile(sess.query(func.sum(x).label('bar')).statement,
             "SELECT sum(lala(users.id)) AS bar FROM users", dialect=default.DefaultDialect()) 
 
 
@@ -109,7 +109,7 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL):
 
         assert [User(id=8), User(id=9)] == create_session().query(User).order_by(User.id).slice(1,3).from_self().all()
         assert [User(id=8)] == list(create_session().query(User).filter(User.id.in_([8,9])).from_self().order_by(User.id)[0:1])
-    
+
     def test_join(self):
         assert [
             (User(id=8), Address(id=2)),
@@ -118,7 +118,7 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL):
             (User(id=9), Address(id=5))
         ] == create_session().query(User).filter(User.id.in_([8,9])).from_self().\
             join('addresses').add_entity(Address).order_by(User.id, Address.id).all()
-    
+
     def test_group_by(self):
         eq_(
             create_session().query(Address.user_id, func.count(Address.id).label('count')).\
@@ -132,14 +132,14 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL):
                             group_by(Address.user_id).order_by(Address.user_id).all(),
             [(7, 1), (8, 3), (9, 1)]
         )
-        
+
     def test_no_joinedload(self):
         """test that joinedloads are pushed outwards and not rendered in subqueries."""
-        
+
         s = create_session()
-        
+
         oracle_as = not testing.against('oracle') and "AS " or ""
-        
+
         self.assert_compile(
             s.query(User).options(joinedload(User.addresses)).from_self().statement,
             "SELECT anon_1.users_id, anon_1.users_name, addresses_1.id, addresses_1.user_id, "\
@@ -148,12 +148,12 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL):
                 'oracle_as':oracle_as
             }
         )
-            
+
     def test_aliases(self):
         """test that aliased objects are accessible externally to a from_self() call."""
-        
+
         s = create_session()
-        
+
         ualias = aliased(User)
         eq_(
             s.query(User, ualias).filter(User.id > ualias.id).from_self(User.name, ualias.name).
@@ -184,8 +184,8 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL):
                 (u'jack', u'ed@wood.com'), 
                 (u'jack', u'fred@fred.com')]
         )
-        
-        
+
+
     def test_multiple_entities(self):
         sess = create_session()
 
@@ -199,14 +199,14 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL):
 
         eq_(
             sess.query(User, Address).filter(User.id==Address.user_id).filter(Address.id.in_([2, 5])).from_self().options(joinedload('addresses')).first(),
-            
+
             #    order_by(User.id, Address.id).first(),
             (User(id=8, addresses=[Address(), Address(), Address()]), Address(id=2)),
         )
 
     def test_multiple_with_column_entities(self):
         sess = create_session()
-        
+
         eq_(
             sess.query(User.id).from_self().\
                 add_column(func.count().label('foo')).\
@@ -216,7 +216,7 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL):
             [
                 (7,1), (8, 1), (9, 1), (10, 1)
             ]
-            
+
         )
 
 class AddEntityEquivalenceTest(_base.MappedTest, AssertsCompiledSQL):
@@ -252,16 +252,16 @@ class AddEntityEquivalenceTest(_base.MappedTest, AssertsCompiledSQL):
     def setup_classes(cls):
         class A(_fixtures.Base):
             pass
-            
+
         class B(_fixtures.Base):
             pass
-        
+
         class C(B):
             pass
-        
+
         class D(A):
             pass
-            
+
         mapper(A, a, 
                     polymorphic_identity='a', 
                     polymorphic_on=a.c.type,
@@ -276,7 +276,7 @@ class AddEntityEquivalenceTest(_base.MappedTest, AssertsCompiledSQL):
                     )
         mapper(C, c, inherits=B, polymorphic_identity='c')
         mapper(D, d, inherits=A, polymorphic_identity='d')
-        
+
     @classmethod
     @testing.resolve_artifact_names
     def insert_data(cls):
@@ -288,11 +288,11 @@ class AddEntityEquivalenceTest(_base.MappedTest, AssertsCompiledSQL):
             A(name='a2')
             ])
         sess.flush()
-    
+
     @testing.resolve_artifact_names
     def test_add_entity_equivalence(self):
         sess = create_session()
-        
+
         for q in [
             sess.query( A,B).join( A.link),
             sess.query( A).join( A.link).add_entity(B),
@@ -317,8 +317,8 @@ class AddEntityEquivalenceTest(_base.MappedTest, AssertsCompiledSQL):
                     A(bid=2, id=1, name=u'a1', type=u'a')
                 )]
             )
-        
-        
+
+
 class InstancesTest(QueryTest, AssertsCompiledSQL):
 
     def test_from_alias(self):
@@ -388,7 +388,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
                             'users.id = addresses.user_id ORDER BY '
                             'users.id, addresses.id',
                             dialect=default.DefaultDialect())
-                
+
         def go():
             assert self.static.user_address_result == q.all()
         self.assert_sql_count(testing.db, go, 1)
@@ -484,7 +484,7 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
 
     def test_mixed_eager_contains_with_limit(self):
         sess = create_session()
-    
+
         q = sess.query(User)
         def go():
             # outerjoin to User.orders, offset 1/limit 2 so we get user
@@ -529,8 +529,8 @@ class InstancesTest(QueryTest, AssertsCompiledSQL):
                 , isopen=0, id=5)])])
 
         self.assert_sql_count(testing.db, go, 1)
-    
-    
+
+
 class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
 
     def test_values(self):
@@ -542,7 +542,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
         q = sess.query(User)
         q2 = q.select_from(sel).values(User.name)
         eq_(list(q2), [(u'jack',), (u'ed',)])
-    
+
         q = sess.query(User)
         q2 = q.order_by(User.id).\
                 values(User.name, User.name + " " + cast(User.id, String(50)))
@@ -551,7 +551,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
             [(u'jack', u'jack 7'), (u'ed', u'ed 8'), 
             (u'fred', u'fred 9'), (u'chuck', u'chuck 10')]
         )
-    
+
         q2 = q.join('addresses').\
                 filter(User.name.like('%e%')).\
                 order_by(User.id, Address.id).\
@@ -559,20 +559,20 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
         eq_(list(q2), 
                 [(u'ed', u'ed@wood.com'), (u'ed', u'ed@bettyboop.com'), 
                 (u'ed', u'ed@lala.com'), (u'fred', u'fred@fred.com')])
-    
+
         q2 = q.join('addresses').\
                 filter(User.name.like('%e%')).\
                 order_by(desc(Address.email_address)).\
                 slice(1, 3).values(User.name, Address.email_address)
         eq_(list(q2), [(u'ed', u'ed@wood.com'), (u'ed', u'ed@lala.com')])
-    
+
         adalias = aliased(Address)
         q2 = q.join(adalias, 'addresses').\
                 filter(User.name.like('%e%')).\
                 values(User.name, adalias.email_address)
         eq_(list(q2), [(u'ed', u'ed@wood.com'), (u'ed', u'ed@bettyboop.com'), 
                         (u'ed', u'ed@lala.com'), (u'fred', u'fred@fred.com')])
-    
+
         q2 = q.values(func.count(User.name))
         assert q2.next() == (4,)
 
@@ -637,10 +637,10 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
     def test_correlated_subquery(self):
         """test that a subquery constructed from ORM attributes doesn't leak out 
         those entities to the outermost query.
-    
+
         """
         sess = create_session()
-    
+
         subq = select([func.count()]).\
             where(User.id==Address.user_id).\
             correlate(users).\
@@ -668,17 +668,17 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
 
     def test_tuple_labeling(self):
         sess = create_session()
-        
+
         # test pickle + all the protocols !
         for pickled in False, -1, 0, 1, 2:
             for row in sess.query(User, Address).join(User.addresses).all():
                 if pickled is not False:
                     row = util.pickle.loads(util.pickle.dumps(row, pickled))
-                    
+
                 eq_(row.keys(), ['User', 'Address'])
                 eq_(row.User, row[0])
                 eq_(row.Address, row[1])
-        
+
             for row in sess.query(User.name, User.id.label('foobar')):
                 if pickled is not False:
                     row = util.pickle.loads(util.pickle.dumps(row, pickled))
@@ -707,22 +707,22 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
                 eq_(row.keys(), ['User', 'orders'])
                 eq_(row.User, row[0])
                 eq_(row.orders, row[1])
-            
+
             # test here that first col is not labeled, only
             # one name in keys, matches correctly
             for row in sess.query(User.name + 'hoho', User.name):
                 eq_(row.keys(), ['name'])
                 eq_(row[0], row.name + 'hoho')
-            
+
             if pickled is not False:
                 ret = sess.query(User, Address).join(User.addresses).all()
                 util.pickle.loads(util.pickle.dumps(ret, pickled))
-                
+
     def test_column_queries(self):
         sess = create_session()
 
         eq_(sess.query(User.name).all(), [(u'jack',), (u'ed',), (u'fred',), (u'chuck',)])
-    
+
         sel = users.select(User.id.in_([7, 8])).alias()
         q = sess.query(User.name)
         q2 = q.select_from(sel).all()
@@ -733,7 +733,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
             (u'ed', u'ed@bettyboop.com'), (u'ed', u'ed@lala.com'), 
             (u'fred', u'fred@fred.com')
         ])
-    
+
         eq_(sess.query(User.name, func.count(Address.email_address)).\
                     outerjoin(User.addresses).group_by(User.id, User.name).\
                     order_by(User.id).all(), 
@@ -753,7 +753,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
             [(1, User(name='jack',id=7)), (3, User(name='ed',id=8)), 
             (1, User(name='fred',id=9)), (0, User(name='chuck',id=10))]
         )
-    
+
         adalias = aliased(Address)
         eq_(sess.query(User, func.count(adalias.email_address)).\
                 outerjoin(adalias, 'addresses').group_by(User).\
@@ -784,7 +784,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
                 (User(name=u'chuck',id=10), None)
             ]
         )
-    
+
         # anon + select from aliasing
         eq_(
             sess.query(User).join(User.addresses, aliased=True).\
@@ -837,17 +837,17 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
 
     def test_column_from_limited_joinedload(self):
         sess = create_session()
-    
+
         def go():
             results = sess.query(User).limit(1).\
                         options(joinedload('addresses')).\
                         add_column(User.name).all()
             eq_(results, [(User(name='jack'), 'jack')])
         self.assert_sql_count(testing.db, go, 1)
-    
+
     @testing.fails_on('postgresql+pg8000', "'type oid 705 not mapped to py type' (due to literal)")
     def test_self_referential(self):
-    
+
         sess = create_session()
         oalias = aliased(Order)
 
@@ -858,12 +858,12 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
             sess.query(Order, oalias).from_self().filter(Order.user_id==oalias.user_id).\
                     filter(Order.user_id==7).filter(Order.id>oalias.id).\
                     order_by(Order.id, oalias.id),
-        
-            # same thing, but reversed.  
+
+            # same thing, but reversed.
             sess.query(oalias, Order).from_self().filter(oalias.user_id==Order.user_id).\
                             filter(oalias.user_id==7).filter(Order.id<oalias.id).\
                             order_by(oalias.id, Order.id),
-        
+
             # here we go....two layers of aliasing
             sess.query(Order, oalias).filter(Order.user_id==oalias.user_id).\
                             filter(Order.user_id==7).filter(Order.id>oalias.id).\
@@ -877,7 +877,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
                             limit(10).options(joinedload(Order.items)),
 
         ]:
-    
+
             eq_(
             q.all(),
             [
@@ -886,11 +886,11 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
                 (Order(address_id=None,description=u'order 5',isopen=0,user_id=7,id=5), 
                         Order(address_id=1,description=u'order 1',isopen=0,user_id=7,id=1)), 
                 (Order(address_id=None,description=u'order 5',isopen=0,user_id=7,id=5), 
-                        Order(address_id=1,description=u'order 3',isopen=1,user_id=7,id=3))                
+                        Order(address_id=1,description=u'order 3',isopen=1,user_id=7,id=3))
             ]
         )
-        
-        
+
+
         # ensure column expressions are taken from inside the subquery, not restated at the top
         q = sess.query(Order.id, Order.description, literal_column("'q'").label('foo')).\
             filter(Order.description == u'order 3').from_self()
@@ -908,8 +908,8 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
             q.all(),
             [(3, u'order 3', 'q')]
         )
-        
-    
+
+
     def test_multi_mappers(self):
 
         test_session = create_session()
@@ -982,9 +982,9 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
 
     def test_with_entities(self):
         sess = create_session()
-        
+
         q = sess.query(User).filter(User.id==7).order_by(User.name)
-        
+
         self.assert_compile(
             q.with_entities(User.id,Address).\
                     filter(Address.user_id == User.id),
@@ -996,8 +996,8 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
                     'addresses.user_id = users.id ORDER BY '
                     'users.name', 
                 use_default_dialect=True)
-        
-        
+
+
     def test_multi_columns(self):
         sess = create_session()
 
@@ -1011,14 +1011,14 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
 
     def test_add_multi_columns(self):
         """test that add_column accepts a FROM clause."""
-    
+
         sess = create_session()
-    
+
         eq_(
             sess.query(User.id).add_column(users).all(),
             [(7, 7, u'jack'), (8, 8, u'ed'), (9, 9, u'fred'), (10, 10, u'chuck')]
         )
-    
+
     def test_multi_columns_2(self):
         """test aliased/nonalised joins with the usage of add_column()"""
         sess = create_session()
@@ -1035,7 +1035,7 @@ class MixedEntitiesTest(QueryTest, AssertsCompiledSQL):
                                 add_column(func.count(Address.id).label('count'))
         eq_(q.all(), expected)
         sess.expunge_all()
-    
+
         adalias = aliased(Address)
         q = sess.query(User)
         q = q.group_by(users).order_by(User.id).outerjoin(adalias, 'addresses').\
@@ -1131,7 +1131,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
 
     def test_join_mapper_order_by(self):
         """test that mapper-level order_by is adapted to a selectable."""
-    
+
         mapper(User, users, order_by=users.c.id)
 
         sel = users.select(users.c.id.in_([7, 8]))
@@ -1145,14 +1145,14 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
 
     def test_differentiate_self_external(self):
         """test some different combinations of joining a table to a subquery of itself."""
-        
+
         mapper(User, users)
-        
+
         sess = create_session()
 
         sel = sess.query(User).filter(User.id.in_([7, 8])).subquery()
         ualias = aliased(User)
-        
+
         self.assert_compile(
             sess.query(User).join(sel, User.id>sel.c.id),
             "SELECT users.id AS users_id, users.name AS users_name FROM "
@@ -1160,7 +1160,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
             "users WHERE users.id IN (:id_1, :id_2)) AS anon_1 ON users.id > anon_1.id",
             use_default_dialect=True
         )
-    
+
         self.assert_compile(
             sess.query(ualias).select_from(sel).filter(ualias.id>sel.c.id),
             "SELECT users_1.id AS users_1_id, users_1.name AS users_1_name FROM "
@@ -1188,8 +1188,8 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
             "IN (:id_1, :id_2)) AS anon_1 JOIN users AS users_1 ON users_1.id > anon_1.id",
             use_default_dialect=True
         )
-        
-        
+
+
         # this one uses an explicit join(left, right, onclause) so works
         self.assert_compile(
             sess.query(ualias).select_from(join(sel, ualias, ualias.id>sel.c.id)),
@@ -1198,9 +1198,9 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
             "IN (:id_1, :id_2)) AS anon_1 JOIN users AS users_1 ON users_1.id > anon_1.id",
             use_default_dialect=True
         )
-        
-        
-        
+
+
+
     def test_join_no_order_by(self):
         mapper(User, users)
 
@@ -1242,7 +1242,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
                 (User(name='ed',id=8), Address(user_id=8,email_address='ed@lala.com',id=4))
             ]
         )
-    
+
 
     def test_more_joins(self):
         mapper(User, users, properties={
@@ -1321,7 +1321,7 @@ class SelectFromTest(QueryTest, AssertsCompiledSQL):
                         ])
                 ])
         self.assert_sql_count(testing.db, go, 1)
-        
+
         sess.expunge_all()
         sel2 = orders.select(orders.c.id.in_([1,2,3]))
         eq_(sess.query(Order).select_from(sel2).\
@@ -1386,7 +1386,7 @@ class CustomJoinTest(QueryTest):
             closed_orders = relationship(Order, primaryjoin = and_(orders.c.isopen == 0, users.c.id==orders.c.user_id), lazy='select')
         ))
         q = create_session().query(User)
-        
+
         eq_(
             q.join('open_orders', 'items', aliased=True).filter(Item.id==4).\
                         join('closed_orders', 'items', aliased=True).filter(Item.id==3).all(),
@@ -1407,7 +1407,7 @@ class ExternalColumnsTest(QueryTest):
 
     def test_external_columns(self):
         """test querying mappings that reference external columns or selectables."""
-    
+
         mapper(User, users, properties={
             'concat': column_property((users.c.id * 2)),
             'count': column_property(
@@ -1421,7 +1421,7 @@ class ExternalColumnsTest(QueryTest):
         })
 
         sess = create_session()
-    
+
         sess.query(Address).options(joinedload('user')).all()
 
         eq_(sess.query(User).all(), 
@@ -1451,7 +1451,7 @@ class ExternalColumnsTest(QueryTest):
                             order_by(Address.id).all(), 
                     address_result)
             self.assert_sql_count(testing.db, go, 1)
-    
+
         ualias = aliased(User)
         eq_(
             sess.query(Address, ualias).join(ualias, 'user').all(), 
@@ -1559,16 +1559,16 @@ class TestOverlyEagerEquivalentCols(_base.MappedTest):
             pass
         class Sub2(_base.ComparableEntity):
             pass
-    
+
         mapper(Base, base, properties={
             'sub1':relationship(Sub1),
             'sub2':relationship(Sub2)
         })
-    
+
         mapper(Sub1, sub1)
         mapper(Sub2, sub2)
         sess = create_session()
-    
+
         s11 = Sub1(data='s11')
         s12 = Sub1(data='s12')
         s2 = Sub2(data='s2')
@@ -1577,12 +1577,12 @@ class TestOverlyEagerEquivalentCols(_base.MappedTest):
         sess.add(b1)
         sess.add(b2)
         sess.flush()
-    
+
         # theres an overlapping ForeignKey here, so not much option except
         # to artifically control the flush order
         b2.sub2 = [s2]
         sess.flush()
-    
+
         q = sess.query(Base).outerjoin('sub2', aliased=True)
         assert sub1.c.id not in q._filter_aliases.equivalents
 
index e3c5eee9900f515a15a38f3e8311ebb5675d937c..79da5fc7a0ca65bb49f8fa20a130947ed4ce11c7 100644 (file)
@@ -46,11 +46,11 @@ class GenerativeQueryTest(_base.MappedTest):
         sess = create_session()
         query = sess.query(Foo).order_by(Foo.id)
         orig = query.all()
-        
+
         assert query[1] == orig[1]
         assert query[-4] == orig[-4]
         assert query[-1] == orig[-1]
-        
+
         assert list(query[10:20]) == orig[10:20]
         assert list(query[10:]) == orig[10:]
         assert list(query[:10]) == orig[:10]
@@ -61,7 +61,7 @@ class GenerativeQueryTest(_base.MappedTest):
         assert list(query[-2:-5]) == orig[-2:-5]
         assert list(query[-5:-2]) == orig[-5:-2]
         assert list(query[:-2]) == orig[:-2]
-        
+
         assert query[10:20][5] == orig[10:20][5]
 
     @testing.uses_deprecated('Call to deprecated function apply_max')
@@ -71,7 +71,7 @@ class GenerativeQueryTest(_base.MappedTest):
         query = sess.query(Foo)
         assert query.count() == 100
         assert sess.query(func.min(foo.c.bar)).filter(foo.c.bar<30).one() == (0,)
-        
+
         assert sess.query(func.max(foo.c.bar)).filter(foo.c.bar<30).one() == (29,)
         # Py3K
         #assert query.filter(foo.c.bar<30).values(sa.func.max(foo.c.bar)).__next__()[0] == 29
@@ -80,7 +80,7 @@ class GenerativeQueryTest(_base.MappedTest):
         assert query.filter(foo.c.bar<30).values(sa.func.max(foo.c.bar)).next()[0] == 29
         assert query.filter(foo.c.bar<30).values(sa.func.max(foo.c.bar)).next()[0] == 29
         # end Py2K
-    
+
     @testing.fails_if(lambda:testing.against('mysql+mysqldb') and
             testing.db.dialect.dbapi.version_info[:4] == (1, 2, 1, 'gamma'),
             "unknown incompatibility")
index 66794ad4be9bda9d27af8c36f9ddf0e0462f442f..eb62ef40e00a543e86e0bb2976608e1196e0c55a 100644 (file)
@@ -17,12 +17,12 @@ class ImmediateTest(_fixtures.FixtureTest):
             'addresses':relationship(Address)
         })
         sess = create_session()
-        
+
         l = sess.query(User).options(immediateload(User.addresses)).filter(users.c.id==7).all()
         eq_(len(sess.identity_map), 2)
-        
+
         sess.close()
-        
+
         eq_(
             [User(id=7, addresses=[Address(id=1, email_address='jack@bean.com')])],
             l
@@ -36,11 +36,11 @@ class ImmediateTest(_fixtures.FixtureTest):
             'addresses':relationship(Address, lazy='immediate')
         })
         sess = create_session()
-        
+
         l = sess.query(User).filter(users.c.id==7).all()
         eq_(len(sess.identity_map), 2)
         sess.close()
-        
+
         eq_(
             [User(id=7, addresses=[Address(id=1, email_address='jack@bean.com')])],
             l
index 3d3c96c6a7e5f53e2f7dafb688c67b2d5125640f..18dca8e45dee527ad02401618a142aee0abdf53c 100644 (file)
@@ -651,16 +651,16 @@ class MiscTest(_base.ORMTest):
 
         a = A()
         assert not a.bs
-    
+
     def test_uninstrument(self):
         class A(object):pass
-        
+
         manager = instrumentation.register_class(A)
-        
+
         assert instrumentation.manager_of_class(A) is manager
         instrumentation.unregister_class(A)
         assert instrumentation.manager_of_class(A) is None
-        
+
     def test_compileonattr_rel_backref_a(self):
         m = MetaData()
         t1 = Table('t1', m,
index 5ae16919ff03d9dcc3938371e721d3d57e026c9f..af6109b9a2846244503de1cac3f0462b3e12ef50 100644 (file)
@@ -61,7 +61,7 @@ class QueryTest(_fixtures.FixtureTest):
 
 class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
     run_setup_mappers = 'once'
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('companies', metadata,
@@ -80,12 +80,12 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
            Column('engineer_name', String(50)),
            Column('primary_language', String(50)),
           )
-     
+
         Table('machines', metadata,
             Column('machine_id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('name', String(50)),
             Column('engineer_id', Integer, ForeignKey('engineers.person_id')))
-        
+
         Table('managers', metadata,
            Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
            Column('status', String(30)),
@@ -101,7 +101,7 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
             Column('paperwork_id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('description', String(50)),
             Column('person_id', Integer, ForeignKey('people.person_id')))
-    
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_classes(cls):
@@ -140,11 +140,11 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
                     inherits=Person, polymorphic_identity='manager')
         mapper(Boss, boss, inherits=Manager, polymorphic_identity='boss')
         mapper(Paperwork, paperwork)
-    
+
     @testing.resolve_artifact_names
     def test_single_prop(self):
         sess = create_session()
-    
+
         self.assert_compile(
             sess.query(Company).join(Company.employees),
             "SELECT companies.company_id AS companies_company_id, companies.name AS companies_name "
@@ -176,9 +176,9 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
             "WHERE companies.company_id = people.company_id AND engineers.primary_language ="
             " :primary_language_1",
             use_default_dialect=True
-            
+
         )
-            
+
     @testing.resolve_artifact_names
     def test_single_prop_of_type(self):
         sess = create_session()
@@ -200,7 +200,7 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
     @testing.resolve_artifact_names
     def test_prop_with_polymorphic(self):
         sess = create_session()
-        
+
         self.assert_compile(
             sess.query(Person).with_polymorphic(Manager).
                     join('paperwork').filter(Paperwork.description.like('%review%')),
@@ -216,7 +216,7 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
                 "ORDER BY people.person_id"
                 , use_default_dialect=True
             )
-        
+
         self.assert_compile(
             sess.query(Person).with_polymorphic(Manager).
                     join('paperwork', aliased=True).
@@ -234,7 +234,7 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
     @testing.resolve_artifact_names
     def test_explicit_polymorphic_join(self):
         sess = create_session()
-        
+
         self.assert_compile(
             sess.query(Company).join(Engineer).filter(Engineer.engineer_name=='vlad'),
             "SELECT companies.company_id AS companies_company_id, companies.name AS "
@@ -275,7 +275,7 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
     def test_multiple_adaption(self):
         """test that multiple filter() adapters get chained together "
         and work correctly within a multiple-entry join()."""
-        
+
         sess = create_session()
 
         self.assert_compile(
@@ -295,7 +295,7 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
             "anon_1.people_company_id WHERE anon_1.people_name = :name_1"
             , use_default_dialect = True
         )
-        
+
         mach_alias = machines.select()
         self.assert_compile(
             sess.query(Company).join(people.join(engineers), Company.employees).
@@ -324,7 +324,7 @@ class InheritedJoinTest(_base.MappedTest, AssertsCompiledSQL):
 
 
 class JoinTest(QueryTest, AssertsCompiledSQL):
-    
+
     def test_single_name(self):
         sess = create_session()
 
@@ -357,21 +357,21 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "ON addresses.id = orders.address_id"
             , use_default_dialect=True
         )
-    
+
     def test_multi_tuple_form(self):
         """test the 'tuple' form of join, now superceded by the two-element join() form.
-        
+
         Not deprecating this style as of yet.
-        
+
         """
-        
+
         sess = create_session()
-        
+
         #assert_raises(
         #    sa.exc.SADeprecationWarning,
         #    sess.query(User).join, (Order, User.id==Order.user_id)
         #)
-        
+
         self.assert_compile(
             sess.query(User).join((Order, User.id==Order.user_id)),
             "SELECT users.id AS users_id, users.name AS users_name "
@@ -390,7 +390,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "order_items_1.item_id",
             use_default_dialect=True
         )
-        
+
         # the old "backwards" form
         self.assert_compile(
             sess.query(User).join(("orders", Order)),
@@ -398,7 +398,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "FROM users JOIN orders ON users.id = orders.user_id",
             use_default_dialect=True
         )
-        
+
     def test_single_prop(self):
         sess = create_session()
         self.assert_compile(
@@ -424,7 +424,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "FROM orders AS orders_1 JOIN users ON users.id = orders_1.user_id"
             , use_default_dialect=True
         )
-        
+
         # another nonsensical query.  (from [ticket:1537]).
         # in this case, the contract of "left to right" is honored
         self.assert_compile(
@@ -434,7 +434,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "orders AS orders_2 JOIN users ON users.id = orders_2.user_id"
             , use_default_dialect=True
         )
-        
+
         self.assert_compile(
             sess.query(User).join(User.orders, Order.items),
             "SELECT users.id AS users_id, users.name AS users_name FROM users "
@@ -442,7 +442,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "ON orders.id = order_items_1.order_id JOIN items ON items.id = order_items_1.item_id"
             , use_default_dialect=True
         )
-        
+
         ualias = aliased(User)
         self.assert_compile(
             sess.query(ualias).join(ualias.orders),
@@ -450,7 +450,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "FROM users AS users_1 JOIN orders ON users_1.id = orders.user_id"
             , use_default_dialect=True
         )
-        
+
         # this query is somewhat nonsensical.  the old system didn't render a correct
         # query for this.   In this case its the most faithful to what was asked -
         # there's no linkage between User.orders and "oalias", so two FROM elements
@@ -484,7 +484,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "WHERE users.name = :name_1) AS anon_1 JOIN orders ON anon_1.users_id = orders.user_id"
             , use_default_dialect=True
         )
-        
+
         self.assert_compile(
             sess.query(User).join(User.addresses, aliased=True).filter(Address.email_address=='foo'),
             "SELECT users.id AS users_id, users.name AS users_name "
@@ -502,7 +502,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "WHERE items_1.id = :id_1"
             , use_default_dialect=True
         )
-        
+
         # test #1 for [ticket:1706]
         ualias = aliased(User)
         self.assert_compile(
@@ -515,7 +515,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "= addresses.user_id"
             , use_default_dialect=True
         )
-        
+
         # test #2 for [ticket:1706]
         ualias2 = aliased(User)
         self.assert_compile(
@@ -528,7 +528,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "ON users_2.id = addresses.user_id JOIN orders ON users_1.id = orders.user_id"
             , use_default_dialect=True
         )
-        
+
     def test_overlapping_paths(self):
         for aliased in (True,False):
             # load a user who has an order that contains item id 3 and address id 1 (order 3, owned by jack)
@@ -540,10 +540,10 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
         result = create_session().query(User).outerjoin('orders', 'items').\
                 filter_by(id=3).outerjoin('orders','address').filter_by(id=1).all()
         assert [User(id=7, name='jack')] == result
-    
+
     def test_from_joinpoint(self):
         sess = create_session()
-        
+
         for oalias,ialias in [(True, True), (False, False), (True, False), (False, True)]:
             eq_(
                 sess.query(User).join('orders', aliased=oalias).\
@@ -563,7 +563,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
                                 filter(Item.description=='item 4').all(),
                 []
             )
-        
+
         orderalias = aliased(Order)
         itemalias = aliased(Item)
         eq_(
@@ -579,11 +579,11 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
                                 filter(itemalias.description=='item 4').all(),
             []
         )
-    
+
     def test_join_nonmapped_column(self):
         """test that the search for a 'left' doesn't trip on non-mapped cols"""
         sess = create_session()
-        
+
         # intentionally join() with a non-existent "left" side
         self.assert_compile(
             sess.query(User.id, literal_column('foo')).join(Order.user),
@@ -591,13 +591,13 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "orders JOIN users ON users.id = orders.user_id"
             , use_default_dialect=True
         )
-        
-        
-        
+
+
+
     def test_backwards_join(self):
         # a more controversial feature.  join from
         # User->Address, but the onclause is Address.user.
-        
+
         sess = create_session()
 
         eq_(
@@ -612,7 +612,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             sess.query(User, Address).join(Address.user).filter(Address.email_address=='ed@wood.com').all(),
             [(User(id=8,name=u'ed'), Address(email_address='ed@wood.com'))]
         )
-        
+
         # this was the controversial part.  now, raise an error if the feature is abused.
         # before the error raise was added, this would silently work.....
         assert_raises(
@@ -626,10 +626,10 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             sa_exc.InvalidRequestError,
             sess.query(User).join, adalias, Address.user,
         )
-        
+
     def test_multiple_with_aliases(self):
         sess = create_session()
-        
+
         ualias = aliased(User)
         oalias1 = aliased(Order)
         oalias2 = aliased(Order)
@@ -645,7 +645,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
 
     def test_select_from_orm_joins(self):
         sess = create_session()
-        
+
         ualias = aliased(User)
         oalias1 = aliased(Order)
         oalias2 = aliased(Order)
@@ -702,18 +702,18 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "users_1_name FROM users AS users_1 JOIN orders AS orders_1 ON users_1.id = orders_1.user_id, "
             "users JOIN orders AS orders_2 ON users.id = orders_2.user_id "
             "WHERE orders_1.user_id = :user_id_1 OR orders_2.user_id = :user_id_2",
-            
+
             use_default_dialect=True
         )
-        
-        
+
+
     def test_overlapping_backwards_joins(self):
         sess = create_session()
 
         oalias1 = aliased(Order)
         oalias2 = aliased(Order)
-        
-        # this is invalid SQL - joins from orders_1/orders_2 to User twice.  
+
+        # this is invalid SQL - joins from orders_1/orders_2 to User twice.
         # but that is what was asked for so they get it !
         self.assert_compile(
             sess.query(User).join(oalias1.user).join(oalias2.user),
@@ -724,9 +724,9 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
 
     def test_replace_multiple_from_clause(self):
         """test adding joins onto multiple FROM clauses"""
-        
+
         sess = create_session()
-        
+
         self.assert_compile(
             sess.query(Address, User).join(Address.dingaling).join(User.orders, Order.items),
             "SELECT addresses.id AS addresses_id, addresses.user_id AS addresses_user_id, "
@@ -736,7 +736,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "ON orders.id = order_items_1.order_id JOIN items ON items.id = order_items_1.item_id",
             use_default_dialect = True
         )
-    
+
     def test_multiple_adaption(self):
         sess = create_session()
 
@@ -747,7 +747,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "JOIN items AS items_1 ON items_1.id = order_items_1.item_id WHERE orders_1.id = :id_1 AND items_1.id = :id_2",
             use_default_dialect=True
         )
-    
+
     def test_onclause_conditional_adaption(self):
         sess = create_session()
 
@@ -764,8 +764,8 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "ON orders_1.id = order_items.order_id AND order_items.item_id = items_1.id",
             use_default_dialect=True
         )
-        
-        
+
+
         oalias = orders.select()
         self.assert_compile(
             sess.query(User).join(oalias, User.orders).
@@ -779,21 +779,21 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "ON anon_1.id = order_items.order_id AND order_items.item_id = items.id",
             use_default_dialect=True
         )
-        
+
         # query.join(<stuff>, aliased=True).join(target, sql_expression)
         # or: query.join(path_to_some_joined_table_mapper).join(target, sql_expression)
-        
+
     def test_pure_expression_error(self):
         sess = create_session()
-        
+
         assert_raises_message(sa.exc.InvalidRequestError, "Could not find a FROM clause to join from", sess.query(users).join, addresses)
-        
-        
+
+
     def test_orderby_arg_bug(self):
         sess = create_session()
         # no arg error
         result = sess.query(User).join('orders', aliased=True).order_by(Order.id).reset_joinpoint().order_by(users.c.id).all()
-    
+
     def test_no_onclause(self):
         sess = create_session()
 
@@ -812,7 +812,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
                             .filter(Item.description == 'item 4').all(),
             [User(name='jack')]
         )
-        
+
     def test_clause_onclause(self):
         sess = create_session()
 
@@ -860,8 +860,8 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
                                 all(),
             [User(name='fred')]
         )
-        
-        
+
+
     def test_aliased_classes(self):
         sess = create_session()
 
@@ -903,9 +903,9 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
 
     def test_expression_onclauses(self):
         sess = create_session()
-        
+
         subq = sess.query(User).subquery()
-        
+
         self.assert_compile(
             sess.query(User).join(subq, User.name==subq.c.name),
             "SELECT users.id AS users_id, users.name AS users_name "
@@ -913,8 +913,8 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "AS name FROM users) AS anon_1 ON users.name = anon_1.name",
             use_default_dialect=True
         )
-        
-        
+
+
         subq = sess.query(Order).subquery()
         self.assert_compile(
             sess.query(User).join(subq, User.id==subq.c.user_id),
@@ -925,15 +925,15 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "anon_1 ON users.id = anon_1.user_id",
             use_default_dialect=True
         )
-            
+
         self.assert_compile(
             sess.query(User).join(Order, User.id==Order.user_id),
             "SELECT users.id AS users_id, users.name AS users_name "
             "FROM users JOIN orders ON users.id = orders.user_id",
             use_default_dialect=True
         )
-        
-        
+
+
     def test_implicit_joins_from_aliases(self):
         sess = create_session()
         OrderAlias = aliased(Order)
@@ -947,7 +947,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
                 Order(address_id=1,description=u'order 3',isopen=1,user_id=7,id=3)
             ]
         )
-         
+
         eq_(
             sess.query(User, OrderAlias, Item.description).
                         join(OrderAlias, 'orders').
@@ -959,11 +959,11 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
                 (User(name=u'jack',id=7), Order(address_id=1,description=u'order 3',isopen=1,user_id=7,id=3), u'item 3'), 
                 (User(name=u'fred',id=9), Order(address_id=4,description=u'order 2',isopen=0,user_id=9,id=2), u'item 3')
             ]
-        )   
-        
+        )
+
     def test_aliased_classes_m2m(self):
         sess = create_session()
-        
+
         (order1, order2, order3, order4, order5) = sess.query(Order).all()
         (item1, item2, item3, item4, item5) = sess.query(Item).all()
         expected = [
@@ -980,7 +980,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             (order4, item5),
             (order5, item5),
         ]
-        
+
         q = sess.query(Order)
         q = q.add_entity(Item).select_from(join(Order, Item, 'items')).order_by(Order.id, Item.id)
         l = q.all()
@@ -996,7 +996,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
                 (order3, item3),
             ]
         )
-    
+
     def test_joins_from_adapted_entities(self):
 
         # test for #1853
@@ -1034,7 +1034,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
                             '(SELECT users.id AS id FROM users) AS '
                             'anon_2 ON anon_2.id = anon_1.users_id',
                             use_default_dialect=True)
-        
+
     def test_reset_joinpoint(self):
         for aliased in (True, False):
             # load a user who has an order that contains item id 3 and address id 1 (order 3, owned by jack)
@@ -1043,7 +1043,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
 
             result = create_session().query(User).outerjoin('orders', 'items', aliased=aliased).filter_by(id=3).reset_joinpoint().outerjoin('orders','address', aliased=aliased).filter_by(id=1).all()
             assert [User(id=7, name='jack')] == result
-    
+
     def test_overlap_with_aliases(self):
         oalias = orders.alias('oalias')
 
@@ -1083,7 +1083,7 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
         # the left half of the join condition of the any() is aliased.
         q = sess.query(User).join('orders', aliased=True).filter(Order.items.any(Item.description=='item 4'))
         assert [User(id=7)] == q.all()
-        
+
         # test that aliasing gets reset when join() is called
         q = sess.query(User).join('orders', aliased=True).filter(Order.description=="order 3").join('orders', aliased=True).filter(Order.description=="order 5")
         assert q.count() == 1
@@ -1106,35 +1106,35 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
         )
 
     def test_plain_table(self):
-            
+
         sess = create_session()
-        
+
         eq_(
             sess.query(User.name).join(addresses, User.id==addresses.c.user_id).order_by(User.id).all(),
             [(u'jack',), (u'ed',), (u'ed',), (u'ed',), (u'fred',)]
         )
-    
+
     def test_no_joinpoint_expr(self):
         sess = create_session()
-        
+
         # these are consistent regardless of
         # select_from() being present.
-        
+
         assert_raises_message(
             sa_exc.InvalidRequestError,
             "Could not find a FROM",
             sess.query(users.c.id).join, User
         )
-        
+
         assert_raises_message(
             sa_exc.InvalidRequestError,
             "Could not find a FROM",
             sess.query(users.c.id).select_from(users).join, User
         )
-    
+
     def test_select_from(self):
         """Test that the left edge of the join can be set reliably with select_from()."""
-        
+
         sess = create_session()
         self.assert_compile(
             sess.query(Item.id).select_from(User).join(User.orders).join(Order.items),
@@ -1152,16 +1152,16 @@ class JoinTest(QueryTest, AssertsCompiledSQL):
             "SELECT items.id AS items_id FROM users JOIN items ON users.id = items.id",
             use_default_dialect=True
         )
-        
-        
-        
-        
+
+
+
+
     def test_from_self_resets_joinpaths(self):
         """test a join from from_self() doesn't confuse joins inside the subquery
         with the outside.
         """
         sess = create_session()
-        
+
         self.assert_compile(
             sess.query(Item).join(Item.keywords).from_self(Keyword).join(Item.keywords),
             "SELECT keywords.id AS keywords_id, keywords.name AS keywords_name FROM "
@@ -1222,30 +1222,30 @@ class MultiplePathTest(_base.MappedTest, AssertsCompiledSQL):
 class SelfRefMixedTest(_base.MappedTest, AssertsCompiledSQL):
     run_setup_mappers = 'once'
     __dialect__ = default.DefaultDialect()
-    
+
     @classmethod
     def define_tables(cls, metadata):
         nodes = Table('nodes', metadata,
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('parent_id', Integer, ForeignKey('nodes.id'))
         )
-        
+
         sub_table = Table('sub_table', metadata,
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('node_id', Integer, ForeignKey('nodes.id')),
         )
-        
+
         assoc_table = Table('assoc_table', metadata,
             Column('left_id', Integer, ForeignKey('nodes.id')),
             Column('right_id', Integer, ForeignKey('nodes.id'))
         )
-        
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_classes(cls):
         class Node(Base):
             pass
-        
+
         class Sub(Base):
             pass
 
@@ -1272,7 +1272,7 @@ class SelfRefMixedTest(_base.MappedTest, AssertsCompiledSQL):
             "FROM nodes JOIN nodes AS nodes_1 ON nodes.id = nodes_1.parent_id "
             "JOIN sub_table ON nodes_1.id = sub_table.node_id"
         )
-    
+
         self.assert_compile(
             sess.query(Node).join(n1, Node.children).join(Sub, Node.subs),
             "SELECT nodes.id AS nodes_id, nodes.parent_id AS nodes_parent_id "
@@ -1292,7 +1292,7 @@ class SelfRefMixedTest(_base.MappedTest, AssertsCompiledSQL):
             "assoc_table_1.left_id JOIN nodes AS nodes_1 ON nodes_1.id = "
             "assoc_table_1.right_id JOIN sub_table ON nodes_1.id = sub_table.node_id",
         )
-    
+
         self.assert_compile(
             sess.query(Node).join(n1, Node.assoc).join(Sub, Node.subs),
             "SELECT nodes.id AS nodes_id, nodes.parent_id AS nodes_parent_id "
@@ -1300,8 +1300,8 @@ class SelfRefMixedTest(_base.MappedTest, AssertsCompiledSQL):
             "assoc_table_1.left_id JOIN nodes AS nodes_1 ON nodes_1.id = "
             "assoc_table_1.right_id JOIN sub_table ON nodes.id = sub_table.node_id",
         )
-        
-    
+
+
 class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
     run_setup_mappers = 'once'
     run_inserts = 'once'
@@ -1314,17 +1314,17 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('parent_id', Integer, ForeignKey('nodes.id')),
             Column('data', String(30)))
-        
+
     @classmethod
     def insert_data(cls):
         # TODO: somehow using setup_classes()
         # here normally is screwing up the other tests.
-        
+
         global Node, Sub
         class Node(Base):
             def append(self, node):
                 self.children.append(node)
-        
+
         mapper(Node, nodes, properties={
             'children':relationship(Node, lazy='select', join_depth=3,
                 backref=backref('parent', remote_side=[nodes.c.id])
@@ -1342,7 +1342,7 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
         sess.add(n1)
         sess.flush()
         sess.close()
-    
+
     @testing.resolve_artifact_names
     def test_join(self):
         sess = create_session()
@@ -1353,24 +1353,24 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
         ret = sess.query(Node.data).join(Node.children, aliased=True).filter_by(data='n122').all()
         assert ret == [('n12',)]
 
-    
+
         node = sess.query(Node).join('children', 'children', aliased=True).filter_by(data='n122').first()
         assert node.data=='n1'
 
         node = sess.query(Node).filter_by(data='n122').join('parent', aliased=True).filter_by(data='n12').\
             join('parent', aliased=True, from_joinpoint=True).filter_by(data='n1').first()
         assert node.data == 'n122'
-    
+
     @testing.resolve_artifact_names
     def test_string_or_prop_aliased(self):
         """test that join('foo') behaves the same as join(Cls.foo) in a self
         referential scenario.
-        
+
         """
-        
+
         sess = create_session()
         nalias = aliased(Node, sess.query(Node).filter_by(data='n1').subquery())
-        
+
         q1 = sess.query(nalias).join(nalias.children, aliased=True).\
                 join(Node.children, from_joinpoint=True)
 
@@ -1388,7 +1388,7 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
                 "nodes_1.parent_id JOIN nodes ON nodes_1.id = nodes.parent_id",
                 use_default_dialect=True
             )
-        
+
         q1 = sess.query(Node).join(nalias.children, aliased=True).\
                 join(Node.children, aliased=True, from_joinpoint=True).\
                 join(Node.children, from_joinpoint=True)
@@ -1396,7 +1396,7 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
         q2 = sess.query(Node).join(nalias.children, aliased=True).\
                 join("children", aliased=True, from_joinpoint=True).\
                 join("children", from_joinpoint=True)
-                
+
         for q in (q1, q2):
             self.assert_compile(
                 q,
@@ -1409,16 +1409,16 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
                 "JOIN nodes ON nodes_2.id = nodes.parent_id",
                 use_default_dialect=True
             )
-        
+
     @testing.resolve_artifact_names
     def test_from_self_inside_excludes_outside(self):
         """test the propagation of aliased() from inside to outside
         on a from_self()..
         """
         sess = create_session()
-        
+
         n1 = aliased(Node)
-        
+
         # n1 is not inside the from_self(), so all cols must be maintained
         # on the outside
         self.assert_compile(
@@ -1438,7 +1438,7 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
             join(grandparent, parent.parent).\
                 filter(Node.data=='n122').filter(parent.data=='n12').\
                 filter(grandparent.data=='n1').from_self().limit(1)
-        
+
         # parent, grandparent *are* inside the from_self(), so they 
         # should get aliased to the outside.
         self.assert_compile(
@@ -1465,14 +1465,14 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
             {'param_1':1},
             use_default_dialect=True
         )
-        
+
     @testing.resolve_artifact_names
     def test_explicit_join(self):
         sess = create_session()
-    
+
         n1 = aliased(Node)
         n2 = aliased(Node)
-        
+
         self.assert_compile(
             join(Node, n1, 'children').join(n2, 'children'),
             "nodes JOIN nodes AS nodes_1 ON nodes.id = nodes_1.parent_id JOIN nodes AS nodes_2 ON nodes_1.id = nodes_2.parent_id",
@@ -1500,7 +1500,7 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
             "JOIN nodes AS nodes_2 ON nodes_1.id = nodes_2.parent_id",
             use_default_dialect=True
         )
-    
+
         self.assert_compile(
             sess.query(Node).join(n1, Node.children).join(n2, Node.children),
             "SELECT nodes.id AS nodes_id, nodes.parent_id AS nodes_parent_id, nodes.data AS "
@@ -1508,14 +1508,14 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
             "JOIN nodes AS nodes_2 ON nodes.id = nodes_2.parent_id",
             use_default_dialect=True
         )
-    
+
         node = sess.query(Node).select_from(join(Node, n1, 'children')).filter(n1.data=='n122').first()
         assert node.data=='n12'
-    
+
         node = sess.query(Node).select_from(join(Node, n1, 'children').join(n2, 'children')).\
             filter(n2.data=='n122').first()
         assert node.data=='n1'
-    
+
         # mix explicit and named onclauses
         node = sess.query(Node).select_from(join(Node, n1, Node.id==n1.parent_id).join(n2, 'children')).\
             filter(n2.data=='n122').first()
@@ -1529,11 +1529,11 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
             list(sess.query(Node).select_from(join(Node, n1, 'parent').join(n2, 'parent')).\
             filter(and_(Node.data=='n122', n1.data=='n12', n2.data=='n1')).values(Node.data, n1.data, n2.data)),
             [('n122', 'n12', 'n1')])
-    
+
     @testing.resolve_artifact_names
     def test_join_to_nonaliased(self):
         sess = create_session()
-    
+
         n1 = aliased(Node)
 
         # using 'n1.parent' implicitly joins to unaliased Node
@@ -1541,18 +1541,18 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
             sess.query(n1).join(n1.parent).filter(Node.data=='n1').all(),
             [Node(parent_id=1,data=u'n11',id=2), Node(parent_id=1,data=u'n12',id=3), Node(parent_id=1,data=u'n13',id=4)]
         )
-    
+
         # explicit (new syntax)
         eq_(
             sess.query(n1).join(Node, n1.parent).filter(Node.data=='n1').all(),
             [Node(parent_id=1,data=u'n11',id=2), Node(parent_id=1,data=u'n12',id=3), Node(parent_id=1,data=u'n13',id=4)]
         )
-    
-        
+
+
     @testing.resolve_artifact_names
     def test_multiple_explicit_entities(self):
         sess = create_session()
-    
+
         parent = aliased(Node)
         grandparent = aliased(Node)
         eq_(
@@ -1602,8 +1602,8 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
                     options(joinedload(Node.children)).first(),
             (Node(data='n122'), Node(data='n12'), Node(data='n1'))
         )
-    
-    
+
+
     @testing.resolve_artifact_names
     def test_any(self):
         sess = create_session()
@@ -1615,7 +1615,7 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
     @testing.resolve_artifact_names
     def test_has(self):
         sess = create_session()
-    
+
         eq_(sess.query(Node).filter(Node.parent.has(Node.data=='n12')).order_by(Node.id).all(), 
             [Node(data='n121'),Node(data='n122'),Node(data='n123')])
         eq_(sess.query(Node).filter(Node.parent.has(Node.data=='n122')).all(), [])
@@ -1624,7 +1624,7 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
     @testing.resolve_artifact_names
     def test_contains(self):
         sess = create_session()
-    
+
         n122 = sess.query(Node).filter(Node.data=='n122').one()
         eq_(sess.query(Node).filter(Node.children.contains(n122)).all(), [Node(data='n12')])
 
@@ -1634,10 +1634,10 @@ class SelfReferentialTest(_base.MappedTest, AssertsCompiledSQL):
     @testing.resolve_artifact_names
     def test_eq_ne(self):
         sess = create_session()
-    
+
         n12 = sess.query(Node).filter(Node.data=='n12').one()
         eq_(sess.query(Node).filter(Node.parent==n12).all(), [Node(data='n121'),Node(data='n122'),Node(data='n123')])
-    
+
         eq_(sess.query(Node).filter(Node.parent != n12).all(), [Node(data='n1'), Node(data='n11'), Node(data='n12'), Node(data='n13')])
 
 class SelfReferentialM2MTest(_base.MappedTest):
@@ -1651,7 +1651,7 @@ class SelfReferentialM2MTest(_base.MappedTest):
         nodes = Table('nodes', metadata,
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('data', String(30)))
-        
+
         node_to_nodes =Table('node_to_nodes', metadata,
             Column('left_node_id', Integer, ForeignKey('nodes.id'),primary_key=True),
             Column('right_node_id', Integer, ForeignKey('nodes.id'),primary_key=True),
@@ -1660,7 +1660,7 @@ class SelfReferentialM2MTest(_base.MappedTest):
     @classmethod
     def insert_data(cls):
         global Node
-    
+
         class Node(Base):
             pass
 
@@ -1678,7 +1678,7 @@ class SelfReferentialM2MTest(_base.MappedTest):
         n5 = Node(data='n5')
         n6 = Node(data='n6')
         n7 = Node(data='n7')
-    
+
         n1.children = [n2, n3, n4]
         n2.children = [n3, n6, n7]
         n3.children = [n5, n4]
@@ -1703,7 +1703,7 @@ class SelfReferentialM2MTest(_base.MappedTest):
 
     def test_explicit_join(self):
         sess = create_session()
-    
+
         n1 = aliased(Node)
         eq_(
             sess.query(Node).select_from(join(Node, n1, 'children')).filter(n1.data.in_(['n3', 'n7'])).order_by(Node.id).all(),
index 1bf7eecaf88f361649908846e1b65eeb7842ef19..3208d060e0db476b8297dd6fbf207716292a6da0 100644 (file)
@@ -191,7 +191,7 @@ class LazyTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_many_to_one_binds(self):
         mapper(Address, addresses, primary_key=[addresses.c.user_id, addresses.c.email_address])
-        
+
         mapper(User, users, properties = dict(
             address = relationship(Address, uselist=False,
                 primaryjoin=sa.and_(users.c.id==addresses.c.user_id, addresses.c.email_address=='ed@bettyboop.com')
@@ -207,7 +207,7 @@ class LazyTest(_fixtures.FixtureTest):
             ], 
             list(q)
         )
-        
+
 
     @testing.resolve_artifact_names
     def test_double(self):
@@ -217,9 +217,9 @@ class LazyTest(_fixtures.FixtureTest):
         closedorders = sa.alias(orders, 'closedorders')
 
         mapper(Address, addresses)
-        
+
         mapper(Order, orders)
-        
+
         open_mapper = mapper(Order, openorders, non_primary=True)
         closed_mapper = mapper(Order, closedorders, non_primary=True)
         mapper(User, users, properties = dict(
@@ -306,10 +306,10 @@ class LazyTest(_fixtures.FixtureTest):
 
         class SmallintDecorator(TypeDecorator):
             impl = SmallInteger
-        
+
         class SomeDBInteger(sa.Integer):
             pass
-            
+
         for tt in [
             Integer,
             SmallInteger,
index f3d3d583d30612450a2de11f5a5e0e7117bb21b1..dee3f193c42d3e41a54ffe67e674a00988aa1f4c 100644 (file)
@@ -40,7 +40,7 @@ class MutableTypesTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_modified_status(self):
         f1 = Foo(data = pickleable.Bar(4,5))
-        
+
         session = Session()
         session.add(f1)
         session.commit()
@@ -52,27 +52,27 @@ class MutableTypesTest(_base.MappedTest):
         f2.data.y = 19
         assert f2 in session.dirty
         assert 'data' not in sa.orm.attributes.instance_state(f2).unmodified
-    
+
     @testing.resolve_artifact_names
     def test_mutations_persisted(self):
         f1 = Foo(data = pickleable.Bar(4,5))
-        
+
         session = Session()
         session.add(f1)
         session.commit()
         f1.data
         session.close()
-        
+
         f2 = session.query(Foo).first()
         f2.data.y = 19
         session.commit()
         f2.data
         session.close()
-        
+
         f3 = session.query(Foo).first()
         ne_(f3.data,f1.data)
         eq_(f3.data, pickleable.Bar(4, 19))
-        
+
     @testing.resolve_artifact_names
     def test_no_unnecessary_update(self):
         f1 = Foo(data = pickleable.Bar(4,5), val = u'hi')
@@ -82,7 +82,7 @@ class MutableTypesTest(_base.MappedTest):
         session.commit()
 
         self.sql_count_(0, session.commit)
-        
+
         f1.val = u'someothervalue'
         self.assert_sql(testing.db, session.commit, [
             ("UPDATE mutable_t SET val=:val "
@@ -95,7 +95,7 @@ class MutableTypesTest(_base.MappedTest):
             ("UPDATE mutable_t SET data=:data, val=:val "
              "WHERE mutable_t.id = :mutable_t_id",
              {'mutable_t_id': f1.id, 'val': u'hi', 'data':f1.data})])
-        
+
     @testing.resolve_artifact_names
     def test_mutated_state_resurrected(self):
         f1 = Foo(data = pickleable.Bar(4,5), val = u'hi')
@@ -119,7 +119,7 @@ class MutableTypesTest(_base.MappedTest):
         """test that a non-mutable attribute event subsequent to
         a mutable event prevents the object from falling into
         resurrected state.
-        
+
          """
         f1 = Foo(data = pickleable.Bar(4, 5), val=u'some val')
         session = Session()
@@ -130,7 +130,7 @@ class MutableTypesTest(_base.MappedTest):
         f1.val=u'some new val'
 
         assert sa.orm.attributes.instance_state(f1)._strong_obj is not None
-        
+
         del f1
         session.commit()
         eq_(
@@ -141,11 +141,11 @@ class MutableTypesTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_non_mutated_state_not_resurrected(self):
         f1 = Foo(data = pickleable.Bar(4,5))
-        
+
         session = Session()
         session.add(f1)
         session.commit()
-        
+
         session = Session()
         f1 = session.query(Foo).first()
         del f1
@@ -159,7 +159,7 @@ class MutableTypesTest(_base.MappedTest):
     def test_scalar_no_net_change_no_update(self):
         """Test that a no-net-change on a scalar attribute event
         doesn't cause an UPDATE for a mutable state.
-        
+
          """
 
         f1 = Foo(val=u'hi')
@@ -177,45 +177,45 @@ class MutableTypesTest(_base.MappedTest):
     def test_expire_attribute_set(self):
         """test no SELECT emitted when assigning to an expired
         mutable attribute.
-        
+
         """
-        
+
         f1 = Foo(data = pickleable.Bar(4, 5), val=u'some val')
         session = Session()
         session.add(f1)
         session.commit()
-        
+
         assert 'data' not in f1.__dict__
         def go():
             f1.data = pickleable.Bar(10, 15)
         self.sql_count_(0, go)
         session.commit()
-        
+
         eq_(f1.data.x, 10)
 
     @testing.resolve_artifact_names
     def test_expire_mutate(self):
         """test mutations are detected on an expired mutable
         attribute."""
-        
+
         f1 = Foo(data = pickleable.Bar(4, 5), val=u'some val')
         session = Session()
         session.add(f1)
         session.commit()
-        
+
         assert 'data' not in f1.__dict__
         def go():
             f1.data.x = 10
         self.sql_count_(1, go)
         session.commit()
-        
+
         eq_(f1.data.x, 10)
-        
+
     @testing.resolve_artifact_names
     def test_deferred_attribute_set(self):
         """test no SELECT emitted when assigning to a deferred
         mutable attribute.
-        
+
         """
         sa.orm.clear_mappers()
         mapper(Foo, mutable_t, properties={
@@ -226,22 +226,22 @@ class MutableTypesTest(_base.MappedTest):
         session = Session()
         session.add(f1)
         session.commit()
-        
+
         session.close()
-        
+
         f1 = session.query(Foo).first()
         def go():
             f1.data = pickleable.Bar(10, 15)
         self.sql_count_(0, go)
         session.commit()
-        
+
         eq_(f1.data.x, 10)
 
     @testing.resolve_artifact_names
     def test_deferred_mutate(self):
         """test mutations are detected on a deferred mutable
         attribute."""
-        
+
         sa.orm.clear_mappers()
         mapper(Foo, mutable_t, properties={
             'data':sa.orm.deferred(mutable_t.c.data)
@@ -251,15 +251,15 @@ class MutableTypesTest(_base.MappedTest):
         session = Session()
         session.add(f1)
         session.commit()
-        
+
         session.close()
-        
+
         f1 = session.query(Foo).first()
         def go():
             f1.data.x = 10
         self.sql_count_(1, go)
         session.commit()
-        
+
         def go():
             eq_(f1.data.x, 10)
         self.sql_count_(1, go)
index 3e7ddb8c2a58936fc22aeeca1d8db771fd34cc42..f8a080f3f4f3ea973269d07efba3cd1e68200fc3 100644 (file)
@@ -15,19 +15,19 @@ class FlushOnPendingTest(AssertsExecutionResults, TestBase):
     def setUp(self):
         global Parent, Child, Base
         Base= declarative_base()
-        
+
         class Parent(Base):
             __tablename__ = 'parent'
-    
+
             id= Column(Integer, primary_key=True, test_needs_autoincrement=True)
             name = Column(String(50), nullable=False)
             children = relationship("Child", load_on_pending=True)
-            
+
         class Child(Base):
             __tablename__ = 'child'
             id= Column(Integer, primary_key=True, test_needs_autoincrement=True)
             parent_id = Column(Integer, ForeignKey('parent.id'))
-    
+
         Base.metadata.create_all(engine)
 
     def tearDown(self):
@@ -35,38 +35,38 @@ class FlushOnPendingTest(AssertsExecutionResults, TestBase):
 
     def test_annoying_autoflush_one(self):
         sess = Session(engine)
-        
+
         p1 = Parent()
         sess.add(p1)
         p1.children = []
 
     def test_annoying_autoflush_two(self):
         sess = Session(engine)
-        
+
         p1 = Parent()
         sess.add(p1)
         assert p1.children == []
 
     def test_dont_load_if_no_keys(self):
         sess = Session(engine)
-        
+
         p1 = Parent()
         sess.add(p1)
-        
+
         def go():
             assert p1.children == []
         self.assert_sql_count(testing.db, go, 0)
 
 class LoadOnFKsTest(AssertsExecutionResults, TestBase):
-    
+
     def setUp(self):
         global Parent, Child, Base
         Base= declarative_base()
-        
+
         class Parent(Base):
             __tablename__ = 'parent'
             __table_args__ = {'mysql_engine':'InnoDB'}
-            
+
             id= Column(Integer, primary_key=True, test_needs_autoincrement=True)
 
         class Child(Base):
@@ -75,9 +75,9 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
 
             id= Column(Integer, primary_key=True, test_needs_autoincrement=True)
             parent_id = Column(Integer, ForeignKey('parent.id'))
-    
+
             parent = relationship(Parent, backref=backref("children"))
-    
+
         Base.metadata.create_all(engine)
 
         global sess, p1, p2, c1, c2
@@ -91,7 +91,7 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
         assert c1 in sess
 
         sess.commit()
-    
+
     def tearDown(self):
         sess.rollback()
         Base.metadata.drop_all(engine)
@@ -103,7 +103,7 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
         sess.add(c3)
         c3.parent_id = p1.id
         c3.parent = p1
-        
+
         # a side effect of load-on-pending with no autoflush.
         # a change to the backref event handler to check
         # collection membership before assuming "old == new so return"
@@ -117,27 +117,27 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
         sess.add(c3)
         c3.parent_id = p1.id
         c3.parent = p1
-        
+
         assert c3 in p1.children
 
     def test_no_load_on_pending_allows_backref_event(self):
         # users who stick with the program and don't use
         # 'load_on_pending' get expected behavior
-        
+
         sess.autoflush = False
         c3 = Child()
         sess.add(c3)
         c3.parent_id = p1.id
 
         c3.parent = p1
-        
+
         assert c3 in p1.children
-    
+
     def test_autoflush_on_pending(self):
         c3 = Child()
         sess.add(c3)
         c3.parent_id = p1.id
-        
+
         # pendings don't autoflush
         assert c3.parent is None
 
@@ -146,10 +146,10 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
         c3 = Child()
         sess.add(c3)
         c3.parent_id = p1.id
-        
+
         # ...unless the flag is on
         assert c3.parent is p1
-        
+
     def test_load_on_pending_with_set(self):
         Child.parent.property.load_on_pending = True
 
@@ -157,13 +157,13 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
 
         c3 = Child()
         sess.add(c3)
-        
+
         c3.parent_id = p1.id
 
         def go():
             c3.parent = p1
         self.assert_sql_count(testing.db, go, 0)
-        
+
     def test_backref_doesnt_double(self):
         Child.parent.property.load_on_pending = True
         sess.autoflush = False
@@ -175,12 +175,12 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
         c3.parent = p1
         c3.parent = p1
         assert len(p1.children)== 2
-        
+
     def test_m2o_lazy_loader_on_persistent(self):
         """Compare the behaviors from the lazyloader using
         the "committed" state in all cases, vs. the lazyloader
         using the "current" state in all cases except during flush.
-        
+
         """
         for loadfk in (True, False):
             for loadrel in (True, False):
@@ -188,23 +188,23 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
                     for manualflush in (True, False):
                         for fake_autoexpire in (True, False):
                             sess.autoflush = autoflush
-                        
+
                             if loadfk:
                                 c1.parent_id
                             if loadrel:
                                 c1.parent
 
                             c1.parent_id = p2.id
-                    
+
                             if manualflush:
                                 sess.flush()
-                        
+
                             # fake_autoexpire refers to the eventual
                             # auto-expire of 'parent' when c1.parent_id
                             # is altered.
                             if fake_autoexpire:
                                 sess.expire(c1, ['parent'])
-                            
+
                             # old 0.6 behavior
                             #if manualflush and (not loadrel or fake_autoexpire):
                             #    # a flush occurs, we get p2
@@ -219,15 +219,15 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
                             #    # if things were loaded, autoflush doesn't even
                             #    # happen.
                             #    assert c1.parent is p1
-                            
+
                             # new behavior
                             if loadrel and not fake_autoexpire:
                                 assert c1.parent is p1
                             else:
                                 assert c1.parent is p2
-                                
+
                             sess.rollback()
-                    
+
     def test_m2o_lazy_loader_on_pending(self):
         for loadonpending in (False, True):
             for autoflush in (False, True):
@@ -237,15 +237,15 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
                     c2 = Child()
                     sess.add(c2)
                     c2.parent_id = p2.id
-                
+
                     if manualflush:
                        sess.flush()
-                
+
                     if loadonpending or manualflush:
                         assert c2.parent is p2
                     else:
                         assert c2.parent is None
-                
+
                     sess.rollback()
 
     def test_m2o_lazy_loader_on_transient(self):
@@ -256,18 +256,18 @@ class LoadOnFKsTest(AssertsExecutionResults, TestBase):
                         Child.parent.property.load_on_pending = loadonpending
                         sess.autoflush = autoflush
                         c2 = Child()
-                    
+
                         if attach:
                             sess._attach(instance_state(c2))
 
                         c2.parent_id = p2.id
-                
+
                         if manualflush:
                            sess.flush()
-                        
+
                         if loadonpending and attach:
                             assert c2.parent is p2
                         else:
                             assert c2.parent is None
-                
+
                         sess.rollback()
index 0e7a6e40f5c6a91322c9c0eee2d15370b5b9a614..9764ed684a6441f80dc4ee1c2ae7e4bf70f4b92d 100644 (file)
@@ -165,11 +165,11 @@ class M2MTest(_base.MappedTest):
         sess.add_all([p1, p2])
         p1.parent_places.append(p2)
         sess.flush()
-        
+
         sess.expire_all()
         assert p1 in p2.parent_places
         assert p2 in p1.parent_places
-        
+
 
     @testing.resolve_artifact_names
     def test_double(self):
@@ -241,7 +241,7 @@ class M2MTest(_base.MappedTest):
                                             passive_updates=False)
         })
         mapper(Transition, transition)
-        
+
         p1 = Place('place1')
         t1 = Transition('t1')
         p1.transitions.append(t1)
@@ -251,10 +251,10 @@ class M2MTest(_base.MappedTest):
 
         p1.place_id
         p1.transitions
-        
+
         sess.execute("delete from place_input", mapper=Place)
         p1.place_id = 7
-        
+
         assert_raises_message(
             orm_exc.StaleDataError,
             r"UPDATE statement on table 'place_input' expected to "
@@ -262,7 +262,7 @@ class M2MTest(_base.MappedTest):
             sess.commit
         )
         sess.rollback()
-        
+
         p1.place_id
         p1.transitions
         sess.execute("delete from place_input", mapper=Place)
@@ -273,7 +273,7 @@ class M2MTest(_base.MappedTest):
             r"delete 1 row\(s\); Only 0 were matched.",
             sess.commit
         )
-        
+
 class M2MTest2(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -327,7 +327,7 @@ class M2MTest2(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_dupliates_raise(self):
         """test constraint error is raised for dupe entries in a list"""
-        
+
         mapper(Student, student)
         mapper(Course, course, properties={
             'students': relationship(Student, enroll, backref='courses')})
@@ -339,7 +339,7 @@ class M2MTest2(_base.MappedTest):
         s1.courses.append(c1)
         sess.add(s1)
         assert_raises(sa.exc.DBAPIError, sess.flush)
-        
+
     @testing.resolve_artifact_names
     def test_delete(self):
         """A many-to-many table gets cleared out with deletion from the backref side"""
@@ -406,7 +406,7 @@ class M2MTest3(_base.MappedTest):
             'a2s': relationship(A, secondary=c2a2, lazy='joined')})
 
         assert create_session().query(C).with_labels().statement is not None
-        
+
         # TODO: seems like just a test for an ancient exception throw.
         # how about some data/inserts/queries/assertions for this one
 
@@ -427,7 +427,7 @@ class M2MTest4(_base.MappedTest):
             Column('t1', Integer, ForeignKey('table1.col1')),
             Column('t2', Integer, ForeignKey('table2.col1')),
             )
-    
+
     @testing.resolve_artifact_names
     def test_delete_parent(self):
         class A(_base.ComparableEntity):
index 54613c222fcad8324376fe206e38c50da3a16714..2cc180895b4ce3633f379e0032c3119971c356b9 100644 (file)
@@ -31,7 +31,7 @@ class MapperTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_update_attr_keys(self):
         """test that update()/insert() use the correct key when given InstrumentedAttributes."""
-        
+
         mapper(User, users, properties={
             'foobar':users.c.name
         })
@@ -41,11 +41,11 @@ class MapperTest(_fixtures.FixtureTest):
 
         users.update().values({User.foobar:User.foobar + 'foo'}).execute()
         eq_(sa.select([User.foobar]).where(User.foobar=='name1foo').execute().fetchall(), [('name1foo',)])
-        
+
     @testing.resolve_artifact_names
     def test_utils(self):
         from sqlalchemy.orm.util import _is_mapped_class, _is_aliased_class
-        
+
         class Foo(object):
             x = "something"
             @property
@@ -53,7 +53,7 @@ class MapperTest(_fixtures.FixtureTest):
                 return "somethign else"
         m = mapper(Foo, users)
         a1 = aliased(Foo)
-        
+
         f = Foo()
 
         for fn, arg, ret in [
@@ -93,13 +93,13 @@ class MapperTest(_fixtures.FixtureTest):
         """test preservation of mapper compile errors raised during hasattr(),
         as well as for redundant mapper compile calls.  Test that 
         repeated calls don't stack up error messages.
-        
+
         """
-        
+
         mapper(Address, addresses, properties={
             'user':relationship(User)
         })
-        
+
         hasattr(Address.user, 'property')
         for i in range(3):
             assert_raises_message(sa.exc.InvalidRequestError,
@@ -109,7 +109,7 @@ class MapperTest(_fixtures.FixtureTest):
                                   "Original exception was: Class "
                                   "'test.orm._fixtures.User' is not mapped$"
                                   , configure_mappers)
-    
+
     @testing.resolve_artifact_names
     def test_column_prefix(self):
         mapper(User, users, column_prefix='_', properties={
@@ -175,7 +175,7 @@ class MapperTest(_fixtures.FixtureTest):
                               "not represented in the mapper's table",
                               mapper, User, users, properties={'foo'
                               : addresses.c.user_id})
-        
+
     @testing.resolve_artifact_names
     def test_constructor_exc(self):
         """TypeError is raised for illegal constructor args, 
@@ -248,12 +248,12 @@ class MapperTest(_fixtures.FixtureTest):
         m= mapper(User, users)
         assert not m.configured
         configure_mappers()
-        
+
         m2 = mapper(Address, addresses, properties={
                                             'user':relationship(User, backref='addresses')
                                         })
         assert m.get_property('addresses')
-        
+
     @testing.resolve_artifact_names
     def test_add_property(self):
         assert_col = []
@@ -279,7 +279,7 @@ class MapperTest(_fixtures.FixtureTest):
 
         class UCComparator(sa.orm.PropComparator):
             __hash__ = None
-            
+
             def __eq__(self, other):
                 cls = self.prop.parent.class_
                 col = getattr(cls, 'name')
@@ -452,7 +452,7 @@ class MapperTest(_fixtures.FixtureTest):
             def name(self):
                 pass
         class Empty(object):pass
-        
+
         empty = mapper(Empty, t, properties={'empty_id' : t.c.id}, 
                        include_properties=[])
         p_m = mapper(Person, t, polymorphic_on=t.c.type,
@@ -473,12 +473,12 @@ class MapperTest(_fixtures.FixtureTest):
                      column_prefix="p_")
 
         hd_m = mapper(HasDef, t, column_prefix="h_")
-        
+
         fb_m = mapper(Fub, t, include_properties=(t.c.id, t.c.type))
         frb_m = mapper(Frob, t, column_prefix='f_',
                        exclude_properties=(t.c.boss_id,
                        'employee_number', t.c.vendor_id))
-        
+
         configure_mappers()
 
         def assert_props(cls, want):
@@ -490,9 +490,9 @@ class MapperTest(_fixtures.FixtureTest):
             have = set([p.key for p in class_mapper(cls).iterate_properties])
             want = set(want)
             eq_(have, want)
-        
+
         assert_props(HasDef, ['h_boss_id', 'h_employee_number', 'h_id', 
-                                'name', 'h_name', 'h_vendor_id', 'h_type'])    
+                                'name', 'h_name', 'h_vendor_id', 'h_type'])
         assert_props(Person, ['id', 'name', 'type'])
         assert_instrumented(Person, ['id', 'name', 'type'])
         assert_props(Employee, ['boss', 'boss_id', 'employee_number',
@@ -501,10 +501,10 @@ class MapperTest(_fixtures.FixtureTest):
                                                         'id', 'name', 'type'])
         assert_props(Manager, ['boss', 'boss_id', 'employee_number', 'peon',
                                'id', 'name', 'type'])
-                               
+
         # 'peon' and 'type' are both explicitly stated properties
         assert_instrumented(Manager, ['peon', 'type', 'id'])
-        
+
         assert_props(Vendor, ['vendor_id', 'id', 'name', 'type'])
         assert_props(Hoho, ['id', 'name', 'type'])
         assert_props(Lala, ['p_employee_number', 'p_id', 'p_name', 'p_type'])
@@ -521,11 +521,11 @@ class MapperTest(_fixtures.FixtureTest):
             Foo, inherits=Person, polymorphic_identity='foo',
             exclude_properties=('type', ),
             )
-    
+
     @testing.resolve_artifact_names
     def test_mapping_to_join_raises(self):
         """Test implicit merging of two cols raises."""
-        
+
         usersaddresses = sa.join(users, addresses,
                                  users.c.id == addresses.c.user_id)
         assert_raises_message(
@@ -624,12 +624,12 @@ class MapperTest(_fixtures.FixtureTest):
         m1 = mapper(Item, items, primary_key=[items.c.id])
         m2 = mapper(Keyword, keywords, primary_key=keywords.c.id)
         m3 = mapper(User, users, primary_key=(users.c.id,))
-        
+
         assert m1.primary_key[0] is items.c.id
         assert m2.primary_key[0] is keywords.c.id
         assert m3.primary_key[0] is users.c.id
-        
-        
+
+
     @testing.resolve_artifact_names
     def test_custom_join(self):
         """select_from totally replace the FROM parameters."""
@@ -668,7 +668,7 @@ class MapperTest(_fixtures.FixtureTest):
             create_session().query(User).order_by(User.name).all(),
             [User(id=10, name=u'chuck'), User(id=8, name=u'ed'), User(id=9, name=u'fred'), User(id=7, name=u'jack')]
         )
-        
+
     # 'Raises a "expression evaluation not supported" error at prepare time
     @testing.fails_on('firebird', 'FIXME: unknown')
     @testing.resolve_artifact_names
@@ -731,14 +731,14 @@ class MapperTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_override_2(self):
         """exclude_properties cancels the error."""
-        
+
         mapper(User, users,
                exclude_properties=['name'],
                properties=dict(
                    name=relationship(mapper(Address, addresses))))
-        
+
         assert bool(User.name)
-        
+
     @testing.resolve_artifact_names
     def test_override_3(self):
         """The column being named elsewhere also cancels the error,"""
@@ -771,7 +771,7 @@ class MapperTest(_fixtures.FixtureTest):
             adlist = synonym('addresses'),
             adname = synonym('addresses')
         ))
-        
+
         # ensure the synonym can get at the proxied comparators without
         # an explicit compile
         User.name == 'ed'
@@ -783,16 +783,16 @@ class MapperTest(_fixtures.FixtureTest):
 
         # test compile
         assert not isinstance(User.uname == 'jack', bool)
-        
+
         assert User.uname.property
         assert User.adlist.property
-        
+
         sess = create_session()
-        
+
         # test RowTuple names
         row = sess.query(User.id, User.uname).first()
         assert row.uname == row[1]
-        
+
         u = sess.query(User).filter(User.uname=='jack').one()
 
         fixture = self.static.user_address_result[0].addresses
@@ -886,22 +886,22 @@ class MapperTest(_fixtures.FixtureTest):
     def test_comparable(self):
         class extendedproperty(property):
             attribute = 123
-            
+
             def method1(self):
                 return "method1"
-            
+
             def __getitem__(self, key):
                 return 'value'
 
         class UCComparator(sa.orm.PropComparator):
             __hash__ = None
-            
+
             def method1(self):
                 return "uccmethod1"
-                
+
             def method2(self, other):
                 return "method2"
-                
+
             def __eq__(self, other):
                 cls = self.prop.parent.class_
                 col = getattr(cls, 'name')
@@ -940,7 +940,7 @@ class MapperTest(_fixtures.FixtureTest):
                 AttributeError, 
                 "Neither 'extendedproperty' object nor 'UCComparator' object has an attribute 'nonexistent'", 
                 getattr, User.uc_name, 'nonexistent')
-            
+
             # test compile
             assert not isinstance(User.uc_name == 'jack', bool)
             u = q.filter(User.uc_name=='JACK').one()
@@ -973,15 +973,15 @@ class MapperTest(_fixtures.FixtureTest):
             def __eq__(self, other):
                 # lower case comparison
                 return func.lower(self.__clause_element__()) == func.lower(other)
-                
+
             def intersects(self, other):
                 # non-standard comparator
                 return self.__clause_element__().op('&=')(other)
-                
+
         mapper(User, users, properties={
             'name':sa.orm.column_property(users.c.name, comparator_factory=MyComparator)
         })
-        
+
         assert_raises_message(
             AttributeError, 
             "Neither 'InstrumentedAttribute' object nor 'MyComparator' object has an attribute 'nonexistent'", 
@@ -989,7 +989,7 @@ class MapperTest(_fixtures.FixtureTest):
 
         eq_(str((User.name == 'ed').compile(dialect=sa.engine.default.DefaultDialect())) , "lower(users.name) = lower(:lower_1)")
         eq_(str((User.name.intersects('ed')).compile(dialect=sa.engine.default.DefaultDialect())), "users.name &= :name_1")
-        
+
 
     @testing.resolve_artifact_names
     def test_reentrant_compile(self):
@@ -997,7 +997,7 @@ class MapperTest(_fixtures.FixtureTest):
             def post_instrument_class(self, mapper):
                 super(MyFakeProperty, self).post_instrument_class(mapper)
                 configure_mappers()
-            
+
         m1 = mapper(User, users, properties={
             'name':MyFakeProperty(users.c.name)
         })
@@ -1009,13 +1009,13 @@ class MapperTest(_fixtures.FixtureTest):
             def post_instrument_class(self, mapper):
                 super(MyFakeProperty, self).post_instrument_class(mapper)
                 configure_mappers()
-            
+
         m1 = mapper(User, users, properties={
             'name':MyFakeProperty(users.c.name)
         })
         m2 = mapper(Address, addresses)
         configure_mappers()
-        
+
     @testing.resolve_artifact_names
     def test_reconstructor(self):
         recon = []
@@ -1105,7 +1105,7 @@ class MapperTest(_fixtures.FixtureTest):
             pass
         class Sub(Base):
             pass
-        
+
         mapper(Base, users)
         sa.orm.configure_mappers()
 
@@ -1126,14 +1126,14 @@ class MapperTest(_fixtures.FixtureTest):
     def test_unmapped_subclass_error_premap(self):
         class Base(object):
             pass
-            
+
         mapper(Base, users)
-        
+
         class Sub(Base):
             pass
 
         sa.orm.configure_mappers()
-        
+
         # we can create new instances, set attributes.
         s = Sub()
         s.name = 'foo'
@@ -1142,11 +1142,11 @@ class MapperTest(_fixtures.FixtureTest):
             attributes.get_history(s, 'name'),
             (['foo'], (), ())
         )
-        
+
         # using it with an ORM operation, raises
         assert_raises(sa.orm.exc.UnmappedClassError,
                         create_session().add, Sub())
-        
+
     @testing.resolve_artifact_names
     def test_oldstyle_mixin(self):
         class OldStyle:
@@ -1165,7 +1165,7 @@ class MapperTest(_fixtures.FixtureTest):
         mapper(B, users)
 
 class DocumentTest(testing.TestBase):
-        
+
     def test_doc_propagate(self):
         metadata = MetaData()
         t1 = Table('t1', metadata,
@@ -1183,10 +1183,10 @@ class DocumentTest(testing.TestBase):
 
         class Foo(object):
             pass
-        
+
         class Bar(object):
             pass
-            
+
         mapper(Foo, t1, properties={
             'bars':relationship(Bar, 
                                     doc="bar relationship", 
@@ -1205,11 +1205,11 @@ class DocumentTest(testing.TestBase):
         eq_(Foo.hoho.__doc__, "syn of col4")
         eq_(Bar.col1.__doc__, "primary key column")
         eq_(Bar.foo.__doc__, "foo relationship")
-        
-        
-        
+
+
+
 class OptionsTest(_fixtures.FixtureTest):
-    
+
     @testing.fails_if(lambda: True, "0.7 regression, may not support "
                                 "synonyms for relationship")
     @testing.fails_on('maxdb', 'FIXME: unknown')
@@ -1219,7 +1219,7 @@ class OptionsTest(_fixtures.FixtureTest):
             addresses = relationship(mapper(Address, addresses), lazy='select',
                                  order_by=addresses.c.id),
             adlist = synonym('addresses')))
-        
+
         def go():
             sess = create_session()
             u = (sess.query(User).
@@ -1379,9 +1379,9 @@ class OptionsTest(_fixtures.FixtureTest):
             items = relationship(Item, secondary=order_items)
         ))
         mapper(Item, items)
-        
+
         sess = create_session()
-        
+
         oalias = aliased(Order)
         opt1 = sa.orm.joinedload(User.orders, Order.items)
         opt2a, opt2b = sa.orm.contains_eager(User.orders, Order.items, alias=oalias)
@@ -1390,7 +1390,7 @@ class OptionsTest(_fixtures.FixtureTest):
         assert opt1 in ustate.load_options
         assert opt2a not in ustate.load_options
         assert opt2b not in ustate.load_options
-        
+
         import pickle
         pickle.dumps(u1)
 
@@ -1424,7 +1424,7 @@ class DeepOptionsTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_deep_options_2(self):
         """test (joined|subquery)load_all() options"""
-        
+
         sess = create_session()
 
         l = (sess.query(User).
@@ -1491,7 +1491,7 @@ class ValidatorTest(_fixtures.FixtureTest):
             def validate_name(self, key, name):
                 assert name != 'fred'
                 return name + ' modified'
-                
+
         mapper(User, users)
         sess = create_session()
         u1 = User(name='ed')
@@ -1502,7 +1502,7 @@ class ValidatorTest(_fixtures.FixtureTest):
         sess.flush()
         sess.expunge_all()
         eq_(sess.query(User).filter_by(name='ed modified').one(), User(name='ed'))
-        
+
 
     @testing.resolve_artifact_names
     def test_collection(self):
@@ -1511,7 +1511,7 @@ class ValidatorTest(_fixtures.FixtureTest):
             def validate_address(self, key, ad):
                 assert '@' in ad.email_address
                 return ad
-                
+
         mapper(User, users, properties={'addresses':relationship(Address)})
         mapper(Address, addresses)
         sess = create_session()
@@ -1532,12 +1532,12 @@ class ComparatorFactoryTest(_fixtures.FixtureTest, AssertsCompiledSQL):
         class DummyComposite(object):
             def __init__(self, x, y):
                 pass
-        
+
         from sqlalchemy.orm.interfaces import PropComparator
-        
+
         class MyFactory(PropComparator):
             pass
-            
+
         for args in (
             (column_property, users.c.name),
             (deferred, users.c.name),
@@ -1551,11 +1551,11 @@ class ComparatorFactoryTest(_fixtures.FixtureTest, AssertsCompiledSQL):
             fn = args[0]
             args = args[1:]
             fn(comparator_factory=MyFactory, *args)
-        
+
     @testing.resolve_artifact_names
     def test_column(self):
         from sqlalchemy.orm.properties import ColumnProperty
-        
+
         class MyFactory(ColumnProperty.Comparator):
             __hash__ = None
             def __eq__(self, other):
@@ -1581,7 +1581,7 @@ class ComparatorFactoryTest(_fixtures.FixtureTest, AssertsCompiledSQL):
                     User.name == 'ed', 
                     "foobar(users.name) = foobar(:foobar_1)",
                     dialect=default.DefaultDialect())
-        
+
         self.assert_compile(
                     aliased(User).name == 'ed', 
                     "foobar(users_1.name) = foobar(:foobar_1)",
@@ -1600,7 +1600,7 @@ class ComparatorFactoryTest(_fixtures.FixtureTest, AssertsCompiledSQL):
             __hash__ = None
             def __eq__(self, other):
                 return func.foobar(self.__clause_element__().c.id) == func.foobar(other.user_id)
-                
+
         mapper(User, users)
         mapper(Address, addresses, properties={
             'user':relationship(User, comparator_factory=MyFactory, 
@@ -1614,7 +1614,7 @@ class ComparatorFactoryTest(_fixtures.FixtureTest, AssertsCompiledSQL):
         self.assert_compile(aliased(Address).user == User(id=5), "foobar(addresses_1.user_id) = foobar(:foobar_1)", dialect=default.DefaultDialect())
         self.assert_compile(aliased(User).addresses == Address(id=5, user_id=7), "foobar(users_1.id) = foobar(:foobar_1)", dialect=default.DefaultDialect())
 
-    
+
 class DeferredTest(_fixtures.FixtureTest):
 
     @testing.resolve_artifact_names
@@ -1664,7 +1664,7 @@ class DeferredTest(_fixtures.FixtureTest):
             'isopen':synonym('_isopen', map_column=True),
             'description':deferred(orders.c.description, group='foo')
         })
-        
+
         sess = create_session()
         o1 = sess.query(Order).get(1)
         eq_(o1.description, "order 1")
@@ -1810,7 +1810,7 @@ class DeferredTest(_fixtures.FixtureTest):
 
         def go():
             q.all()[0].user_id
-                
+
         self.sql_eq_(go, [
             ("SELECT orders.id AS orders_id, "
              "orders.address_id AS orders_address_id, "
@@ -1913,7 +1913,7 @@ class SecondaryOptionsTest(_base.MappedTest):
     run_inserts = 'once'
 
     run_deletes = None
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table("base", metadata, 
@@ -1930,7 +1930,7 @@ class SecondaryOptionsTest(_base.MappedTest):
         Table('related', metadata,
             Column('id', Integer, ForeignKey('base.id'), primary_key=True),
         )
-        
+
     @classmethod
     @testing.resolve_artifact_names
     def setup_mappers(cls):
@@ -1950,7 +1950,7 @@ class SecondaryOptionsTest(_base.MappedTest):
         })
         mapper(Child2, child2, inherits=Base, polymorphic_identity='child2')
         mapper(Related, related)
-        
+
     @classmethod
     @testing.resolve_artifact_names
     def insert_data(cls):
@@ -1980,12 +1980,12 @@ class SecondaryOptionsTest(_base.MappedTest):
             {'id':5},
             {'id':6},
         ])
-        
+
     @testing.resolve_artifact_names
     def test_contains_eager(self):
         sess = create_session()
-        
-        
+
+
         child1s = sess.query(Child1).join(Child1.related).options(sa.orm.contains_eager(Child1.related)).order_by(Child1.id)
 
         def go():
@@ -1994,7 +1994,7 @@ class SecondaryOptionsTest(_base.MappedTest):
                 [Child1(id=1, related=Related(id=1)), Child1(id=2, related=Related(id=2)), Child1(id=3, related=Related(id=3))]
             )
         self.assert_sql_count(testing.db, go, 1)
-        
+
         c1 = child1s[0]
  
         self.assert_sql_execution(
@@ -2020,7 +2020,7 @@ class SecondaryOptionsTest(_base.MappedTest):
                 [Child1(id=1, related=Related(id=1)), Child1(id=2, related=Related(id=2)), Child1(id=3, related=Related(id=3))]
             )
         self.assert_sql_count(testing.db, go, 1)
-        
+
         c1 = child1s[0]
 
         self.assert_sql_execution(
@@ -2050,7 +2050,7 @@ class SecondaryOptionsTest(_base.MappedTest):
                 [Child1(id=1, related=Related(id=1)), Child1(id=2, related=Related(id=2)), Child1(id=3, related=Related(id=3))]
             )
         self.assert_sql_count(testing.db, go, 4)
-        
+
         c1 = child1s[0]
 
         # this *does* joinedload
@@ -2064,7 +2064,7 @@ class SecondaryOptionsTest(_base.MappedTest):
                 {'param_1':4}
             )
         )
-        
+
 
 class DeferredPopulationTest(_base.MappedTest):
     @classmethod
@@ -2086,7 +2086,7 @@ class DeferredPopulationTest(_base.MappedTest):
 
         mapper(Human, human, properties={"thing": relationship(Thing)})
         mapper(Thing, thing, properties={"name": deferred(thing.c.name)})
-    
+
     @classmethod
     @testing.resolve_artifact_names
     def insert_data(cls):
@@ -2097,7 +2097,7 @@ class DeferredPopulationTest(_base.MappedTest):
         human.insert().execute([
             {"id": 1, "thing_id": 1, "name": "Clark Kent"},
         ])
-        
+
     def _test(self, thing):
         assert "name" in attributes.instance_state(thing).dict
 
@@ -2121,7 +2121,7 @@ class DeferredPopulationTest(_base.MappedTest):
         result = session.query(Thing).first()
         thing = session.query(Thing).options(sa.orm.undefer("name")).first()
         self._test(thing)
-    
+
     @testing.resolve_artifact_names
     def test_joinedload_with_clear(self):
         session = create_session()
@@ -2151,8 +2151,8 @@ class DeferredPopulationTest(_base.MappedTest):
         result = session.query(Human).add_entity(Thing).join("thing").first()
         thing = session.query(Thing).options(sa.orm.undefer("name")).first()
         self._test(thing)
-    
-        
+
+
 
 
 class NoLoadTest(_fixtures.FixtureTest):
@@ -2195,8 +2195,8 @@ class NoLoadTest(_fixtures.FixtureTest):
             )
 
 
-        
-        
+
+
 
 class RequirementsTest(_base.MappedTest):
     """Tests the contract for user classes."""
@@ -2232,14 +2232,14 @@ class RequirementsTest(_base.MappedTest):
         assert_raises(sa.exc.ArgumentError, mapper, OldStyle, ht1)
 
         assert_raises(sa.exc.ArgumentError, mapper, 123)
-        
+
         class NoWeakrefSupport(str):
             pass
 
         # TODO: is weakref support detectable without an instance?
         #self.assertRaises(sa.exc.ArgumentError, mapper, NoWeakrefSupport, t2)
     # end Py2K
-    
+
     @testing.resolve_artifact_names
     def test_comparison_overrides(self):
         """Simple tests to ensure users can supply comparison __methods__.
@@ -2340,7 +2340,7 @@ class RequirementsTest(_base.MappedTest):
         class H1(object):
             def __len__(self):
                 return len(self.get_value())
-            
+
             def get_value(self):
                 self.value = "foobar"
                 return self.value
@@ -2352,10 +2352,10 @@ class RequirementsTest(_base.MappedTest):
             def get_value(self):
                 self.value = "foobar"
                 return self.value
-                
+
         mapper(H1, ht1)
         mapper(H2, ht1)
-        
+
         h1 = H1()
         h1.value = "Asdf"
         h1.value = "asdf asdf" # ding
@@ -2363,7 +2363,7 @@ class RequirementsTest(_base.MappedTest):
         h2 = H2()
         h2.value = "Asdf"
         h2.value = "asdf asdf" # ding
-        
+
 class MagicNamesTest(_base.MappedTest):
 
     @classmethod
@@ -2403,7 +2403,7 @@ class MagicNamesTest(_base.MappedTest):
         sess.add(c)
         sess.flush()
         sess.expunge_all()
-    
+
         for C, M in ((Cartographer, Map),
                      (sa.orm.aliased(Cartographer), sa.orm.aliased(Map))):
             c1 = (sess.query(C).
index 1eafa59e880272fec6fb64c89d4ef2db05929fdc..d07efd9871622d412c009fc71104e13418b49444 100644 (file)
@@ -53,7 +53,7 @@ class MergeTest(_fixtures.FixtureTest):
         def go():
             sess.merge(u)
         self.assert_sql_count(testing.db, go, 0)
-        
+
     @testing.resolve_artifact_names
     def test_transient_to_pending_collection(self):
         mapper(User, users, properties={
@@ -241,9 +241,9 @@ class MergeTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_merge_empty_attributes(self):
         mapper(User, dingalings)
-        
+
         sess = create_session()
-        
+
         # merge empty stuff.  goes in as NULL.
         # not sure what this was originally trying to 
         # test.
@@ -255,17 +255,17 @@ class MergeTest(_fixtures.FixtureTest):
         u2 = User(id=2, data="foo")
         sess.add(u2)
         sess.flush()
-        
+
         # merge User on u2's pk with
         # no "data".
         # value isn't whacked from the destination
         # dict.
         u3 = sess.merge(User(id=2))
         eq_(u3.__dict__['data'], "foo")
-        
+
         # make a change.
         u3.data = 'bar'
-        
+
         # merge another no-"data" user.
         # attribute maintains modified state.
         # (usually autoflush would have happened
@@ -281,12 +281,12 @@ class MergeTest(_fixtures.FixtureTest):
         u5 = User(id=3, data="foo")
         sess.add(u5)
         sess.flush()
-        
+
         # blow it away from u5, but don't
         # mark as expired.  so it would just 
         # be blank.
         del u5.data
-        
+
         # the merge adds expiry to the
         # attribute so that it loads.
         # not sure if I like this - it currently is needed
@@ -300,8 +300,8 @@ class MergeTest(_fixtures.FixtureTest):
         u6.data = None
         u7 = sess.merge(User(id=3))
         assert u6.__dict__['data'] is None
-        
-        
+
+
     @testing.resolve_artifact_names
     def test_merge_irregular_collection(self):
         mapper(User, users, properties={
@@ -427,27 +427,27 @@ class MergeTest(_fixtures.FixtureTest):
         a1 = Address(email_address="asdf", user=u1)
         sess.add(a1)
         sess.flush()
-        
+
         a2 = Address(id=a1.id, email_address="bar", user=User(name="hoho"))
         a2 = sess.merge(a2)
         sess.flush()
-        
+
         # no expire of the attribute
-        
+
         assert a2.__dict__['user'] is u1
-        
+
         # merge succeeded
         eq_(
             sess.query(Address).all(),
             [Address(id=a1.id, email_address="bar")]
         )
-        
+
         # didn't touch user
         eq_(
             sess.query(User).all(),
             [User(name="fred")]
         )
-        
+
     @testing.resolve_artifact_names
     def test_one_to_many_cascade(self):
 
@@ -492,17 +492,17 @@ class MergeTest(_fixtures.FixtureTest):
             'user':relationship(User)
         })
         mapper(User, users)
-        
+
         u1 = User(id=1, name="u1")
         a1 =Address(id=1, email_address="a1", user=u1)
         u2 = User(id=2, name="u2")
-        
+
         sess = create_session()
         sess.add_all([a1, u2])
         sess.flush()
-        
+
         a1.user = u2
-        
+
         sess2 = create_session()
         a2 = sess2.merge(a1)
         eq_(
@@ -510,9 +510,9 @@ class MergeTest(_fixtures.FixtureTest):
             ([u2], (), [attributes.PASSIVE_NO_RESULT])
         )
         assert a2 in sess2.dirty
-        
+
         sess.refresh(a1)
-        
+
         sess2 = create_session()
         a2 = sess2.merge(a1, load=False)
         eq_(
@@ -520,7 +520,7 @@ class MergeTest(_fixtures.FixtureTest):
             ((), [u1], ())
         )
         assert a2 not in sess2.dirty
-        
+
     @testing.resolve_artifact_names
     def test_many_to_many_cascade(self):
 
@@ -609,18 +609,18 @@ class MergeTest(_fixtures.FixtureTest):
         sess.add(u)
         sess.commit()
         sess.close()
-        
+
         u2 = User(id=7, name=None, address=None)
         u3 = sess.merge(u2)
         assert u3.name is None
         assert u3.address is None
-        
+
         sess.close()
-        
+
         a1 = Address(id=1, user=None)
         a2 = sess.merge(a1)
         assert a2.user is None
-        
+
     @testing.resolve_artifact_names
     def test_transient_no_load(self):
         mapper(User, users)
@@ -863,7 +863,7 @@ class MergeTest(_fixtures.FixtureTest):
             'uid':synonym('id'),
             'foobar':comparable_property(User.Comparator,User.value),
         })
-        
+
         sess = create_session()
         u = User()
         u.name = 'ed'
@@ -875,7 +875,7 @@ class MergeTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_cascade_doesnt_blowaway_manytoone(self):
         """a merge test that was fixed by [ticket:1202]"""
-        
+
         s = create_session(autoflush=True)
         mapper(User, users, properties={
             'addresses':relationship(mapper(Address, addresses),backref='user')})
@@ -889,7 +889,7 @@ class MergeTest(_fixtures.FixtureTest):
         eq_(after_id, other_id)
         eq_(before_id, after_id)
         eq_(a1.user, a2.user)
-            
+
     @testing.resolve_artifact_names
     def test_cascades_dont_autoflush(self):
         sess = create_session(autoflush=True)
@@ -930,7 +930,7 @@ class MergeTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_dont_expire_pending(self):
         """test that pending instances aren't expired during a merge."""
-        
+
         mapper(User, users)
         u = User(id=7)
         sess = create_session(autoflush=True, autocommit=False)
@@ -939,40 +939,40 @@ class MergeTest(_fixtures.FixtureTest):
         def go():
             eq_(u.name, None)
         self.assert_sql_count(testing.db, go, 0)
-    
+
     @testing.resolve_artifact_names
     def test_option_state(self):
         """test that the merged takes on the MapperOption characteristics
         of that which is merged.
-        
+
         """
         class Option(MapperOption):
             propagate_to_loaders = True
-            
+
         opt1, opt2 = Option(), Option()
 
         sess = sessionmaker()()
-        
+
         umapper = mapper(User, users)
-        
+
         sess.add_all([
             User(id=1, name='u1'),
             User(id=2, name='u2'),
         ])
         sess.commit()
-        
+
         sess2 = sessionmaker()()
         s2_users = sess2.query(User).options(opt2).all()
-        
+
         # test 1.  no options are replaced by merge options
         sess = sessionmaker()()
         s1_users = sess.query(User).all()
-        
+
         for u in s1_users:
             ustate = attributes.instance_state(u)
             eq_(ustate.load_path, ())
             eq_(ustate.load_options, set())
-            
+
         for u in s2_users:
             sess.merge(u)
 
@@ -980,7 +980,7 @@ class MergeTest(_fixtures.FixtureTest):
             ustate = attributes.instance_state(u)
             eq_(ustate.load_path, (umapper, ))
             eq_(ustate.load_options, set([opt2]))
-        
+
         # test 2.  present options are replaced by merge options
         sess = sessionmaker()()
         s1_users = sess.query(User).options(opt1).all()
@@ -991,12 +991,12 @@ class MergeTest(_fixtures.FixtureTest):
 
         for u in s2_users:
             sess.merge(u)
-            
+
         for u in s1_users:
             ustate = attributes.instance_state(u)
             eq_(ustate.load_path, (umapper, ))
             eq_(ustate.load_options, set([opt2]))
-        
+
 
 class MutableMergeTest(_base.MappedTest):
     @classmethod
@@ -1005,27 +1005,27 @@ class MutableMergeTest(_base.MappedTest):
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('data', PickleType(comparator=operator.eq))
         )
-    
+
     @classmethod
     def setup_classes(cls):
         class Data(_base.ComparableEntity):
             pass
-    
+
     @testing.resolve_artifact_names
     def test_list(self):
         mapper(Data, data)
         sess = sessionmaker()()
         d = Data(data=["this", "is", "a", "list"])
-        
+
         sess.add(d)
         sess.commit()
-        
+
         d2 = Data(id=d.id, data=["this", "is", "another", "list"])
         d3 = sess.merge(d2)
         eq_(d3.data, ["this", "is", "another", "list"])
-        
-        
-        
+
+
+
 class CompositeNullPksTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -1033,19 +1033,19 @@ class CompositeNullPksTest(_base.MappedTest):
             Column('pk1', String(10), primary_key=True),
             Column('pk2', String(10), primary_key=True),
         )
-    
+
     @classmethod
     def setup_classes(cls):
         class Data(_base.ComparableEntity):
             pass
-    
+
     @testing.resolve_artifact_names
     def test_merge_allow_partial(self):
         mapper(Data, data)
         sess = sessionmaker()()
-        
+
         d1 = Data(pk1="someval", pk2=None)
-        
+
         def go():
             return sess.merge(d1)
         self.assert_sql_count(testing.db, go, 1)
@@ -1060,5 +1060,5 @@ class CompositeNullPksTest(_base.MappedTest):
         def go():
             return sess.merge(d1)
         self.assert_sql_count(testing.db, go, 0)
-    
+
 
index f9ce7b3cabecc6ee3aa7a2ed513aee5d7e0b56df..18ebb5bba58c23163694faf0e53ef63283a0bf6e 100644 (file)
@@ -21,7 +21,7 @@ class NaturalPKTest(_base.MappedTest):
             fk_args = dict(deferrable=True, initially='deferred')
         else:
             fk_args = dict(onupdate='cascade')
-            
+
         users = Table('users', metadata,
             Column('username', String(50), primary_key=True),
             Column('fullname', String(100)),
@@ -118,7 +118,7 @@ class NaturalPKTest(_base.MappedTest):
         sess.flush()
         sess.expunge_all()
         assert sess.query(User).get('ed').fullname == 'jack'
-        
+
 
     @testing.fails_on('sqlite', 'sqlite doesnt support ON UPDATE CASCADE')
     @testing.fails_on('oracle', 'oracle doesnt support ON UPDATE CASCADE')
@@ -177,7 +177,7 @@ class NaturalPKTest(_base.MappedTest):
         assert sess.query(Address).get('jack1').username is None
         u1 = sess.query(User).get('fred')
         eq_(User(username='fred', fullname='jack'), u1)
-        
+
 
     @testing.fails_on('sqlite', 'sqlite doesnt support ON UPDATE CASCADE')
     @testing.fails_on('oracle', 'oracle doesnt support ON UPDATE CASCADE')
@@ -243,7 +243,7 @@ class NaturalPKTest(_base.MappedTest):
         u1 = User(username='jack', fullname='jack')
         sess.add(u1)
         sess.flush()
-        
+
         a1 = Address(email='jack1')
         u1.address = a1
         sess.add(a1)
@@ -265,7 +265,7 @@ class NaturalPKTest(_base.MappedTest):
 
         sess.expunge_all()
         eq_([Address(username='ed')], sess.query(Address).all())
-        
+
     @testing.fails_on('sqlite', 'sqlite doesnt support ON UPDATE CASCADE')
     @testing.fails_on('oracle', 'oracle doesnt support ON UPDATE CASCADE')
     def test_bidirectional_passive(self):
@@ -376,7 +376,7 @@ class NaturalPKTest(_base.MappedTest):
         eq_(['jack'], [u.username for u in r[0].users])
         eq_(Item(itemname='item2'), r[1])
         eq_(['ed', 'jack'], sorted([u.username for u in r[1].users]))
-        
+
         sess.expunge_all()
         u2 = sess.query(User).get(u2.username)
         u2.username='wendy'
@@ -386,41 +386,41 @@ class NaturalPKTest(_base.MappedTest):
 
 class TransientExceptionTesst(_fixtures.FixtureTest):
     run_inserts = None
-    
+
     @testing.resolve_artifact_names
     def test_transient_exception(self):
         """An object that goes from a pk value to transient/pending
         doesn't count as a "pk" switch.
-        
+
         """
         mapper(User, users)
         mapper(Address, addresses, properties={'user':relationship(User)})
-        
+
         sess = create_session()
         u1 = User(id=5, name='u1')
         ad1 = Address(email_address='e1', user=u1)
         sess.add_all([u1, ad1])
         sess.flush()
-        
+
         make_transient(u1)
         u1.id = None
         u1.username='u2'
         sess.add(u1)
         sess.flush()
-        
+
         eq_(ad1.user_id, 5)
-        
+
         sess.expire_all()
         eq_(ad1.user_id, 5)
         ne_(u1.id, 5)
         ne_(u1.id, None)
         eq_(sess.query(User).count(), 2)
-        
+
 class ReversePKsTest(_base.MappedTest):
     """reverse the primary keys of two entities and ensure bookkeeping
     succeeds."""
-    
-    
+
+
     @classmethod
     def define_tables(cls, metadata):
         Table(
@@ -429,7 +429,7 @@ class ReversePKsTest(_base.MappedTest):
             Column('status', Integer, primary_key=True),
             Column('username', Unicode(50), nullable=False),
             )
-    
+
     @classmethod
     def setup_classes(cls):
         class User(_base.ComparableEntity):
@@ -441,11 +441,11 @@ class ReversePKsTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_reverse(self):
         PUBLISHED, EDITABLE, ARCHIVED = 1, 2, 3
-        
+
         mapper(User, user)
 
         session = sa.orm.sessionmaker()()
-        
+
         a_published = User(1, PUBLISHED, u'a')
         session.add(a_published)
         session.commit()
@@ -473,7 +473,7 @@ class ReversePKsTest(_base.MappedTest):
         assert session.query(User).get([1, PUBLISHED]) is a_published
         assert session.query(User).get([1, EDITABLE]) is a_editable
 
-    
+
 class SelfReferentialTest(_base.MappedTest):
     # mssql, mysql don't allow 
     # ON UPDATE on self-referential keys
@@ -485,7 +485,7 @@ class SelfReferentialTest(_base.MappedTest):
             fk_args = dict(deferrable=True, initially='deferred')
         else:
             fk_args = dict(onupdate='cascade')
-        
+
         Table('nodes', metadata,
               Column('name', String(50), primary_key=True),
               Column('parent', String(50),
@@ -515,7 +515,7 @@ class SelfReferentialTest(_base.MappedTest):
         n4 = Node(name='n13', parentnode=n1)
         sess.add_all([n2, n3, n4])
         sess.commit()
-        
+
         n1.name = 'new n1'
         sess.commit()
         eq_(['new n1', 'new n1', 'new n1'],
@@ -686,7 +686,7 @@ class NonPKCascadeTest(_base.MappedTest):
 class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
     """A primary key mutation cascades onto a foreign key that is itself a
     primary key."""
-    
+
     @classmethod
     def define_tables(cls, metadata):
         if testing.against('oracle'):
@@ -714,7 +714,7 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
             pass
         class Address(_base.ComparableEntity):
             pass
-    
+
     @testing.fails_on('sqlite', 'sqlite doesnt support ON UPDATE CASCADE')
     @testing.fails_on('oracle', 'oracle doesnt support ON UPDATE CASCADE')
     def test_onetomany_passive(self):
@@ -724,20 +724,20 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
     @testing.fails_on_everything_except('sqlite', 'oracle', '+zxjdbc')
     def test_onetomany_nonpassive(self):
         self._test_onetomany(False)
-        
+
     def test_o2m_change_passive(self):
         self._test_o2m_change(True)
-        
+
     def test_o2m_change_nonpassive(self):
         self._test_o2m_change(False)
 
     @testing.resolve_artifact_names
     def _test_o2m_change(self, passive_updates):
         """Change the PK of a related entity to another.
-        
+
         "on update cascade" is not involved here, so the mapper has 
         to do the UPDATE itself.
-        
+
         """
         mapper(User, users, properties={
             'addresses':relationship(Address,
@@ -748,10 +748,10 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
         a1 = Address(username='ed', email='ed@host1')
         u1 = User(username='ed', addresses=[a1])
         u2 = User(username='jack')
-        
+
         sess.add_all([a1, u1, u2])
         sess.flush()
-        
+
         a1.username = 'jack'
         sess.flush()
 
@@ -783,17 +783,17 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
         u1.addresses.remove(a1)
         u2.addresses.append(a1)
         sess.flush()
-    
+
     @testing.fails_on('oracle', 'oracle doesnt support ON UPDATE CASCADE '
                                 'but requires referential integrity')
     @testing.fails_on('sqlite', 'sqlite doesnt support ON UPDATE CASCADE')
     def test_change_m2o_passive(self):
         self._test_change_m2o(True)
-    
+
     @testing.fails_on_everything_except('sqlite', 'oracle', '+zxjdbc')
     def test_change_m2o_nonpassive(self):
         self._test_change_m2o(False)
-    
+
     @testing.resolve_artifact_names
     def _test_change_m2o(self, passive_updates):
         mapper(User, users)
@@ -806,11 +806,11 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
         a1 = Address(user=u1, email='foo@bar')
         sess.add_all([u1, a1])
         sess.flush()
-        
+
         u1.username='edmodified'
         sess.flush()
         eq_(a1.username, 'edmodified')
-        
+
         sess.expire_all()
         eq_(a1.username, 'edmodified')
 
@@ -834,11 +834,11 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
         a1 = Address(user=u1, email='foo@bar')
         sess.add_all([u1, u2, a1])
         sess.flush()
-        
+
         a1.user = u2
         sess.flush()
-        
-    
+
+
     @testing.resolve_artifact_names
     def test_rowswitch_doesntfire(self):
         mapper(User, users)
@@ -849,11 +849,11 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
         sess = create_session()
         u1 = User(username='ed')
         a1 = Address(user=u1, email='ed@host1')
-        
+
         sess.add(u1)
         sess.add(a1)
         sess.flush()
-        
+
         sess.delete(u1)
         sess.delete(a1)
 
@@ -863,7 +863,7 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
         sess.add(a2)
 
         from test.lib.assertsql import CompiledSQL
-        
+
         # test that the primary key columns of addresses are not
         # being updated as well, since this is a row switch.
         self.assert_sql_execution(testing.db,
@@ -875,22 +875,22 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
                          {'etc': 'foo', 'addresses_username':'ed',
                             'addresses_email':'ed@host1'} ),
                     )
-        
-        
+
+
     @testing.resolve_artifact_names
     def _test_onetomany(self, passive_updates):
         """Change the PK of a related entity via foreign key cascade.
-        
+
         For databases that require "on update cascade", the mapper 
         has to identify the row by the new value, not the old, when
         it does the update.
-        
+
         """
         mapper(User, users, properties={
             'addresses':relationship(Address,
                                 passive_updates=passive_updates)})
         mapper(Address, addresses)
-    
+
         sess = create_session()
         a1, a2 = Address(username='ed', email='ed@host1'),\
                     Address(username='ed', email='ed@host2')
@@ -901,7 +901,7 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
         eq_(a2.username, 'ed')
         eq_(sa.select([addresses.c.username]).execute().fetchall(), 
                 [('ed',), ('ed',)])
-        
+
         u1.username = 'jack'
         a2.email='ed@host3'
         sess.flush()
@@ -914,7 +914,7 @@ class CascadeToFKPKTest(_base.MappedTest, testing.AssertsCompiledSQL):
 
 class JoinedInheritanceTest(_base.MappedTest):
     """Test cascades of pk->pk/fk on joined table inh."""
-    
+
     # mssql doesn't allow ON UPDATE on self-referential keys
     __unsupported_on__ = ('mssql',) 
 
@@ -929,7 +929,7 @@ class JoinedInheritanceTest(_base.MappedTest):
             Column('name', String(50), primary_key=True),
             Column('type', String(50), nullable=False),
             test_needs_fk=True)
-        
+
         Table('engineer', metadata,
             Column('name', String(50), ForeignKey('person.name', **fk_args),
                                         primary_key=True),
@@ -965,12 +965,12 @@ class JoinedInheritanceTest(_base.MappedTest):
     @testing.fails_on_everything_except('sqlite', 'oracle', '+zxjdbc')
     def test_pk_nonpassive(self):
         self._test_pk(False)
-        
+
     @testing.fails_on('sqlite', 'sqlite doesnt support ON UPDATE CASCADE')
     @testing.fails_on('oracle', 'oracle doesnt support ON UPDATE CASCADE')
     def test_fk_passive(self):
         self._test_fk(True)
-        
+
     # PG etc. need passive=True to allow PK->PK cascade
     @testing.fails_on_everything_except('sqlite', 'mysql+zxjdbc', 'oracle',
                                                 'postgresql+zxjdbc')
@@ -1000,7 +1000,7 @@ class JoinedInheritanceTest(_base.MappedTest):
         e1.name = 'wally'
         e1.primary_language = 'c++'
         sess.commit()
-        
+
     @testing.resolve_artifact_names
     def _test_fk(self, passive_updates):
         mapper(Person, person, polymorphic_on=person.c.type, 
@@ -1015,9 +1015,9 @@ class JoinedInheritanceTest(_base.MappedTest):
         })
         mapper(Manager, manager, inherits=Person,
                     polymorphic_identity='manager')
-        
+
         sess = sa.orm.sessionmaker()()
-        
+
         m1 = Manager(name='dogbert', paperwork='lots')
         e1, e2 = \
                 Engineer(name='dilbert', primary_language='java', boss=m1),\
@@ -1030,14 +1030,14 @@ class JoinedInheritanceTest(_base.MappedTest):
         eq_(e1.boss_name, 'dogbert')
         eq_(e2.boss_name, 'dogbert')
         sess.expire_all()
-        
+
         m1.name = 'pointy haired'
         e1.primary_language = 'scala'
         e2.primary_language = 'cobol'
         sess.commit()
-        
+
         eq_(e1.boss_name, 'pointy haired')
         eq_(e2.boss_name, 'pointy haired')
-    
-    
-    
+
+
+
index 7097a266ee742b97d1ad44e3e78889b0973d0a96..ff0ac508abff4ed0aeeed8c8905799d53aae66d0 100644 (file)
@@ -47,7 +47,7 @@ class O2OTest(_base.MappedTest):
         session.add(j)
         p = Port(name='fa0/1')
         session.add(p)
-        
+
         j.port=p
         session.flush()
         jid = j.id
index 972b298af2ea890bb0a8eee14b0c0ee5cfaad31e..3383c48b985e49c93bd8265585a771c57430e876 100644 (file)
@@ -18,7 +18,7 @@ User, EmailUser = None, None
 
 class PickleTest(_fixtures.FixtureTest):
     run_inserts = None
-    
+
     @testing.resolve_artifact_names
     def test_transient(self):
         mapper(User, users, properties={
@@ -40,7 +40,7 @@ class PickleTest(_fixtures.FixtureTest):
 
     @testing.resolve_artifact_names
     def test_no_mappers(self):
-        
+
         umapper = mapper(User, users)
         u1 = User(name='ed')
         u1_pickled = pickle.dumps(u1, -1)
@@ -67,21 +67,21 @@ class PickleTest(_fixtures.FixtureTest):
         # this fails unless the InstanceState
         # compiles the mapper
         eq_(str(u1), "User(name='ed')")
-        
+
     @testing.resolve_artifact_names
     def test_serialize_path(self):
         umapper = mapper(User, users, properties={
             'addresses':relationship(Address, backref="user")
         })
         amapper = mapper(Address, addresses)
-        
+
         # this is a "relationship" path with mapper, key, mapper, key
         p1 = (umapper, 'addresses', amapper, 'email_address')
         eq_(
             interfaces.deserialize_path(interfaces.serialize_path(p1)),
             p1
         )
-        
+
         # this is a "mapper" path with mapper, key, mapper, no key
         # at the end.
         p2 = (umapper, 'addresses', amapper, )
@@ -89,14 +89,14 @@ class PickleTest(_fixtures.FixtureTest):
             interfaces.deserialize_path(interfaces.serialize_path(p2)),
             p2
         )
-        
+
         # test a blank path
         p3 = ()
         eq_(
             interfaces.deserialize_path(interfaces.serialize_path(p3)),
             p3
         )
-        
+
     @testing.resolve_artifact_names
     def test_class_deferred_cols(self):
         mapper(User, users, properties={
@@ -134,7 +134,7 @@ class PickleTest(_fixtures.FixtureTest):
             'addresses':relationship(Address, lazy='noload')
         })
         mapper(Address, addresses)
-        
+
         sess = Session()
         u1 = User(name='ed', addresses=[
                         Address(
@@ -145,16 +145,16 @@ class PickleTest(_fixtures.FixtureTest):
         sess.add(u1)
         sess.commit()
         sess.close()
-        
+
         u1 = sess.query(User).options(
                                 lazyload(User.addresses)
                             ).first()
         u2 = pickle.loads(pickle.dumps(u1))
-        
+
         sess = Session()
         sess.add(u2)
         assert u2.addresses
-        
+
     @testing.resolve_artifact_names
     def test_instance_deferred_cols(self):
         mapper(User, users, properties={
@@ -192,11 +192,11 @@ class PickleTest(_fixtures.FixtureTest):
         eq_(u2.name, 'ed')
         assert 'addresses' not in u2.__dict__
         ad = u2.addresses[0]
-        
+
         # mapper options now transmit over merge(),
         # new as of 0.6, so email_address is deferred.
-        assert 'email_address' not in ad.__dict__  
-        
+        assert 'email_address' not in ad.__dict__
+
         eq_(ad.email_address, 'ed@bar.com')
         eq_(u2, User(name='ed', addresses=[Address(email_address='ed@bar.com')]))
 
@@ -218,7 +218,7 @@ class PickleTest(_fixtures.FixtureTest):
         for protocol in -1, 0, 1, 2:
             u2 = pickle.loads(pickle.dumps(u1, protocol))
             eq_(u1, u2)
-        
+
     @testing.resolve_artifact_names
     def test_options_with_descriptors(self):
         mapper(User, users, properties={
@@ -241,17 +241,17 @@ class PickleTest(_fixtures.FixtureTest):
         ]:
             opt2 = pickle.loads(pickle.dumps(opt))
             eq_(opt.key, opt2.key)
-        
+
         u1 = sess.query(User).options(opt).first()
-        
+
         u2 = pickle.loads(pickle.dumps(u1))
-        
+
     def test_collection_setstate(self):
         """test a particular cycle that requires CollectionAdapter 
         to not rely upon InstanceState to deserialize."""
-        
+
         global Child1, Child2, Parent, Screen
-        
+
         m = MetaData()
         c1 = Table('c1', m, 
             Column('parent_id', String, 
@@ -272,7 +272,7 @@ class PickleTest(_fixtures.FixtureTest):
 
         class Parent(_base.ComparableEntity):
             pass
-        
+
         mapper(Parent, p, properties={
             'children1':relationship(Child1),
             'children2':relationship(Child2)
@@ -289,7 +289,7 @@ class PickleTest(_fixtures.FixtureTest):
         screen1.errors = [obj.children1, obj.children2]
         screen2 = Screen(Child2(), screen1)
         pickle.loads(pickle.dumps(screen2))
-        
+
 class PolymorphicDeferredTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -339,7 +339,7 @@ class CustomSetupTeardownTest(_fixtures.FixtureTest):
     def test_rebuild_state(self):
         """not much of a 'test', but illustrate how to 
         remove instance-level state before pickling.
-        
+
         """
         mapper(User, users)
 
@@ -349,12 +349,12 @@ class CustomSetupTeardownTest(_fixtures.FixtureTest):
         u2 = pickle.loads(pickle.dumps(u1))
         attributes.manager_of_class(User).setup_instance(u2)
         assert attributes.instance_state(u2)
-    
+
 class UnpickleSA05Test(_fixtures.FixtureTest):
     """test loading picklestrings from SQLA 0.5."""
-    
+
     __requires__ = ('python2',)
-    
+
     @testing.resolve_artifact_names
     def test_one(self):
         mapper(User, users, properties={
index 15ffaff2f034ea16e5dd44eb11b3993781b7c474..fba77c7832bdee94b7d20c608fd83af61cc874ba 100644 (file)
@@ -66,7 +66,7 @@ class RowTupleTest(QueryTest):
         mapper(User, users, properties={
             'uname':users.c.name
         })
-        
+
         row  = create_session().\
                     query(User.id, User.uname).\
                     filter(User.id==7).first()
@@ -125,7 +125,7 @@ class RowTupleTest(QueryTest):
                 q.column_descriptions,
                 asserted
             )
-        
+
 class GetTest(QueryTest):
     def test_get(self):
         s = create_session()
@@ -140,14 +140,14 @@ class GetTest(QueryTest):
     def test_get_composite_pk_no_result(self):
         s = Session()
         assert s.query(CompositePk).get((100,100)) is None
-        
+
     def test_get_composite_pk_result(self):
         s = Session()
         one_two = s.query(CompositePk).get((1,2))
         assert one_two.i == 1
         assert one_two.j == 2
         assert one_two.k == 3
-    
+
     def test_get_too_few_params(self):
         s = Session()
         q = s.query(CompositePk)
@@ -162,16 +162,16 @@ class GetTest(QueryTest):
         s = Session()
         q = s.query(CompositePk)
         assert_raises(sa_exc.InvalidRequestError, q.get, (7, 10, 100))
-    
+
     def test_get_null_pk(self):
         """test that a mapping which can have None in a 
         PK (i.e. map to an outerjoin) works with get()."""
-        
+
         s = users.outerjoin(addresses)
-        
+
         class UserThing(_base.ComparableEntity):
             pass
-            
+
         mapper(UserThing, s, properties={
             'id':(users.c.id, addresses.c.user_id),
             'address_id':addresses.c.id,
@@ -186,11 +186,11 @@ class GetTest(QueryTest):
         """test that get()/load() does not use preexisting filter/etc. criterion"""
 
         s = create_session()
-        
+
         q = s.query(User).join('addresses').filter(Address.user_id==8)
         assert_raises(sa_exc.InvalidRequestError, q.get, 7)
         assert_raises(sa_exc.InvalidRequestError, s.query(User).filter(User.id==7).get, 19)
-        
+
         # order_by()/get() doesn't raise
         s.query(User).order_by(User.id).get(8)
 
@@ -244,7 +244,7 @@ class GetTest(QueryTest):
             # Py2K
             ustring = 'petit voix m\xe2\x80\x99a'.decode('utf-8')
             # end Py2K
-            
+
             table.insert().execute(id=ustring, data=ustring)
             class LocalFoo(Base):
                 pass
@@ -298,7 +298,7 @@ class GetTest(QueryTest):
 class InvalidGenerationsTest(QueryTest, AssertsCompiledSQL):
     def test_no_limit_offset(self):
         s = create_session()
-        
+
         for q in (
             s.query(User).limit(2),
             s.query(User).offset(2),
@@ -315,31 +315,31 @@ class InvalidGenerationsTest(QueryTest, AssertsCompiledSQL):
             assert_raises(sa_exc.InvalidRequestError, q.group_by, 'foo')
 
             assert_raises(sa_exc.InvalidRequestError, q.having, 'foo')
-    
+
             q.enable_assertions(False).join("addresses")
             q.enable_assertions(False).filter(User.name=='ed')
             q.enable_assertions(False).order_by('foo')
             q.enable_assertions(False).group_by('foo')
-            
+
     def test_no_from(self):
         s = create_session()
-    
+
         q = s.query(User).select_from(users)
         assert_raises(sa_exc.InvalidRequestError, q.select_from, users)
 
         q = s.query(User).join('addresses')
         assert_raises(sa_exc.InvalidRequestError, q.select_from, users)
-        
+
         q = s.query(User).order_by(User.id)
         assert_raises(sa_exc.InvalidRequestError, q.select_from, users)
 
         assert_raises(sa_exc.InvalidRequestError, q.select_from, users)
-        
+
         q.enable_assertions(False).select_from(users)
-        
+
         # this is fine, however
         q.from_self()
-    
+
     def test_invalid_select_from(self):
         s = create_session()
         q = s.query(User)
@@ -351,15 +351,15 @@ class InvalidGenerationsTest(QueryTest, AssertsCompiledSQL):
         q = s.query(User)
         assert_raises(sa_exc.ArgumentError, q.from_statement, User.id==5)
         assert_raises(sa_exc.ArgumentError, q.from_statement, users.join(addresses))
-    
+
     def test_invalid_column(self):
         s = create_session()
         q = s.query(User)
         assert_raises(sa_exc.InvalidRequestError, q.add_column, object())
-    
+
     def test_distinct(self):
         """test that a distinct() call is not valid before 'clauseelement' conditions."""
-        
+
         s = create_session()
         q = s.query(User).distinct()
         assert_raises(sa_exc.InvalidRequestError, q.select_from, User)
@@ -374,7 +374,7 @@ class InvalidGenerationsTest(QueryTest, AssertsCompiledSQL):
         assert_raises(sa_exc.InvalidRequestError, q.select_from, User)
         assert_raises(sa_exc.InvalidRequestError, q.from_statement, text("select * from table"))
         assert_raises(sa_exc.InvalidRequestError, q.with_polymorphic, User)
-        
+
     def test_cancel_order_by(self):
         s = create_session()
 
@@ -399,16 +399,16 @@ class InvalidGenerationsTest(QueryTest, AssertsCompiledSQL):
 
         # after False was set, this should pass
         q._no_select_modifiers("foo")
-        
+
     def test_mapper_zero(self):
         s = create_session()
-        
+
         q = s.query(User, Address)
         assert_raises(sa_exc.InvalidRequestError, q.get, 5)
-        
+
     def test_from_statement(self):
         s = create_session()
-        
+
         q = s.query(User).filter(User.id==5)
         assert_raises(sa_exc.InvalidRequestError, q.from_statement, "x")
 
@@ -423,7 +423,7 @@ class InvalidGenerationsTest(QueryTest, AssertsCompiledSQL):
 
         q = s.query(User).order_by(User.name)
         assert_raises(sa_exc.InvalidRequestError, q.from_statement, "x")
-        
+
 class OperatorTest(QueryTest, AssertsCompiledSQL):
     """test sql.Comparator implementation for MapperProperties"""
 
@@ -455,7 +455,7 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
     def test_comparison(self):
         create_session().query(User)
         ualias = aliased(User)
-        
+
         for (py_op, fwd_op, rev_op) in ((operator.lt, '<', '>'),
                                         (operator.gt, '>', '<'),
                                         (operator.eq, '=', '='),
@@ -486,7 +486,7 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
                 self.assert_(compiled == fwd_sql or compiled == rev_sql,
                              "\n'" + compiled + "'\n does not match\n'" +
                              fwd_sql + "'\n or\n'" + rev_sql + "'")
-    
+
     def test_negated_null(self):
         self._test(User.id == None, "users.id IS NULL")
         self._test(~(User.id==None), "users.id IS NOT NULL")
@@ -496,7 +496,7 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
         self._test(~(Address.user==None), "addresses.user_id IS NOT NULL")
         self._test(None == Address.user, "addresses.user_id IS NULL")
         self._test(~(None == Address.user), "addresses.user_id IS NOT NULL")
-        
+
     def test_relationship(self):
         self._test(User.addresses.any(Address.id==17), 
                         "EXISTS (SELECT 1 "
@@ -506,7 +506,7 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
 
         u7 = User(id=7)
         attributes.instance_state(u7).commit_all(attributes.instance_dict(u7))
-        
+
         self._test(Address.user == u7, ":param_1 = addresses.user_id")
 
         self._test(Address.user != u7, "addresses.user_id != :user_id_1 OR addresses.user_id IS NULL")
@@ -530,7 +530,7 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
             Node.children==None, 
             "NOT (EXISTS (SELECT 1 FROM nodes AS nodes_1 WHERE nodes.id = nodes_1.parent_id))"
         )
-        
+
         self._test(
             Node.parent==None,
             "nodes.parent_id IS NULL"
@@ -545,12 +545,12 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
             nalias.children==None, 
             "NOT (EXISTS (SELECT 1 FROM nodes WHERE nodes_1.id = nodes.parent_id))"
         )
-        
+
         self._test(
                 nalias.children.any(Node.data=='some data'), 
                 "EXISTS (SELECT 1 FROM nodes WHERE "
                 "nodes_1.id = nodes.parent_id AND nodes.data = :data_1)")
-        
+
         # fails, but I think I want this to fail
         #self._test(
         #        Node.children.any(nalias.data=='some data'), 
@@ -567,7 +567,7 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
             Node.parent.has(Node.data=='some data'), 
            "EXISTS (SELECT 1 FROM nodes AS nodes_1 WHERE nodes_1.id = nodes.parent_id AND nodes_1.data = :data_1)"
         )
-        
+
         self._test(
             Node.parent == Node(id=7), 
             ":param_1 = nodes.parent_id"
@@ -582,11 +582,11 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
             nalias.parent != Node(id=7), 
             'nodes_1.parent_id != :parent_id_1 OR nodes_1.parent_id IS NULL'
         )
-        
+
         self._test(
             nalias.children.contains(Node(id=7)), "nodes_1.id = :param_1"
         )
-        
+
     def test_op(self):
         self._test(User.name.op('ilike')('17'), "users.name ilike :name_1")
 
@@ -596,11 +596,11 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
 
     def test_in_on_relationship_not_supported(self):
         assert_raises(NotImplementedError, Address.user.in_, [User(id=5)])
-    
+
     def test_neg(self):
         self._test(-User.id, "-users.id")
         self._test(User.id + -User.id, "users.id + -users.id")
-        
+
     def test_between(self):
         self._test(User.id.between('a', 'b'),
                    "users.id BETWEEN :id_1 AND :id_2")
@@ -623,7 +623,7 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
 
 
 class ExpressionTest(QueryTest, AssertsCompiledSQL):
-        
+
     def test_deferred_instances(self):
         session = create_session()
         s = session.query(User).filter(and_(addresses.c.email_address == bindparam('emailad'), Address.user_id==User.id)).statement
@@ -633,13 +633,13 @@ class ExpressionTest(QueryTest, AssertsCompiledSQL):
 
     def test_scalar_subquery(self):
         session = create_session()
-        
+
         q = session.query(User.id).filter(User.id==7).subquery()
-        
+
         q = session.query(User).filter(User.id==q)
-        
+
         eq_(User(id=7), q.one())
-    
+
     def test_label(self):
         session = create_session()
 
@@ -649,29 +649,29 @@ class ExpressionTest(QueryTest, AssertsCompiledSQL):
             "SELECT (SELECT users.id FROM users WHERE users.id = :id_1) AS foo", 
             use_default_dialect=True
         )
-    
+
     def test_as_scalar(self):
         session = create_session()
 
         q = session.query(User.id).filter(User.id==7).as_scalar()
-        
+
         self.assert_compile(session.query(User).filter(User.id.in_(q)),
                             'SELECT users.id AS users_id, users.name '
                             'AS users_name FROM users WHERE users.id '
                             'IN (SELECT users.id FROM users WHERE '
                             'users.id = :id_1)',
                             use_default_dialect=True)
-        
-        
+
+
     def test_param_transfer(self):
         session = create_session()
-        
+
         q = session.query(User.id).filter(User.id==bindparam('foo')).params(foo=7).subquery()
-        
+
         q = session.query(User).filter(User.id==q)
-        
+
         eq_(User(id=7), q.one())
-        
+
     def test_in(self):
         session = create_session()
         s = session.query(User.id).join(User.addresses).group_by(User.id).having(func.count(Address.id) > 2)
@@ -682,17 +682,17 @@ class ExpressionTest(QueryTest, AssertsCompiledSQL):
 
     def test_union(self):
         s = create_session()
-        
+
         q1 = s.query(User).filter(User.name=='ed').with_labels()
         q2 = s.query(User).filter(User.name=='fred').with_labels()
         eq_(
             s.query(User).from_statement(union(q1, q2).order_by('users_name')).all(),
             [User(name='ed'), User(name='fred')]
         )
-    
+
     def test_select(self):
         s = create_session()
-        
+
         # this is actually not legal on most DBs since the subquery has no alias
         q1 = s.query(User).filter(User.name=='ed')
 
@@ -703,7 +703,7 @@ class ExpressionTest(QueryTest, AssertsCompiledSQL):
             "users.name AS users_name FROM users WHERE users.name = :name_1)",
             dialect=default.DefaultDialect()
         )
-        
+
     def test_join(self):
         s = create_session()
 
@@ -715,7 +715,7 @@ class ExpressionTest(QueryTest, AssertsCompiledSQL):
             s.query(User, adalias).join(adalias, User.id==adalias.user_id).all(),
             [(User(id=7,name=u'jack'), Address(email_address=u'jack@bean.com',user_id=7,id=1))]
         )
-        
+
 # more slice tests are available in test/orm/generative.py
 class SliceTest(QueryTest):
     def test_first(self):
@@ -726,15 +726,15 @@ class SliceTest(QueryTest):
     @testing.only_on('sqlite', 'testing execution but db-specific syntax')
     def test_limit_offset_applies(self):
         """Test that the expected LIMIT/OFFSET is applied for slices.
-        
+
         The LIMIT/OFFSET syntax differs slightly on all databases, and
         query[x:y] executes immediately, so we are asserting against
         SQL strings using sqlite's syntax.
-        
+
         """
         sess = create_session()
         q = sess.query(User)
-        
+
         self.assert_sql(testing.db, lambda: q[10:20], [
             ("SELECT users.id AS users_id, users.name AS users_name FROM users LIMIT :param_1 OFFSET :param_2", {'param_1':10, 'param_2':10})
         ])
@@ -764,7 +764,7 @@ class SliceTest(QueryTest):
         ])
 
 
-    
+
 class FilterTest(QueryTest):
     def test_basic(self):
         assert [User(id=7), User(id=8), User(id=9),User(id=10)] == create_session().query(User).all()
@@ -776,20 +776,20 @@ class FilterTest(QueryTest):
         assert [User(id=8), User(id=9)] == list(create_session().query(User).order_by(User.id)[1:3])
 
         assert User(id=8) == create_session().query(User).order_by(User.id)[1]
-    
+
         assert [] == create_session().query(User).order_by(User.id)[3:3]
         assert [] == create_session().query(User).order_by(User.id)[0:0]
-        
+
     @testing.requires.boolean_col_expressions
     def test_exists(self):
         sess = create_session(testing.db)
-        
+
         assert sess.query(exists().where(User.id==9)).scalar()
         assert not sess.query(exists().where(User.id==29)).scalar()
-        
+
     def test_one_filter(self):
         assert [User(id=8), User(id=9)] == create_session().query(User).filter(User.name.endswith('ed')).all()
-    
+
     def test_contains(self):
         """test comparing a collection to an object instance."""
 
@@ -824,15 +824,15 @@ class FilterTest(QueryTest):
             filter(User.addresses.any(id=4)).all()
 
         assert [User(id=9)] == sess.query(User).filter(User.addresses.any(email_address='fred@fred.com')).all()
-        
+
         # test that any() doesn't overcorrelate
         assert [User(id=7), User(id=8)] == sess.query(User).join("addresses").filter(~User.addresses.any(Address.email_address=='fred@fred.com')).all()
-        
+
         # test that the contents are not adapted by the aliased join
         assert [User(id=7), User(id=8)] == sess.query(User).join("addresses", aliased=True).filter(~User.addresses.any(Address.email_address=='fred@fred.com')).all()
 
         assert [User(id=10)] == sess.query(User).outerjoin("addresses", aliased=True).filter(~User.addresses.any()).all()
-        
+
     @testing.crashes('maxdb', 'can dump core')
     def test_has(self):
         sess = create_session()
@@ -851,10 +851,10 @@ class FilterTest(QueryTest):
         # test has() doesnt' get subquery contents adapted by aliased join
         assert [Address(id=2), Address(id=3), Address(id=4)] == \
             sess.query(Address).join("user", aliased=True).filter(Address.user.has(User.name.like('%ed%'), id=8)).order_by(Address.id).all()
-        
+
         dingaling = sess.query(Dingaling).get(2)
         assert [User(id=9)] == sess.query(User).filter(User.addresses.any(Address.dingaling==dingaling)).all()
-        
+
     def test_contains_m2m(self):
         sess = create_session()
         item = sess.query(Item).get(3)
@@ -864,7 +864,7 @@ class FilterTest(QueryTest):
 
         item2 = sess.query(Item).get(5)
         assert [Order(id=3)] == sess.query(Order).filter(Order.items.contains(item)).filter(Order.items.contains(item2)).all()
-        
+
 
     def test_comparison(self):
         """test scalar comparison to an object instance"""
@@ -888,7 +888,7 @@ class FilterTest(QueryTest):
         # m2m
         eq_(sess.query(Item).filter(Item.keywords==None).order_by(Item.id).all(), [Item(id=4), Item(id=5)])
         eq_(sess.query(Item).filter(Item.keywords!=None).order_by(Item.id).all(), [Item(id=1),Item(id=2), Item(id=3)])
-    
+
     def test_filter_by(self):
         sess = create_session()
         user = sess.query(User).get(8)
@@ -901,10 +901,10 @@ class FilterTest(QueryTest):
         # one to many generates WHERE NOT EXISTS
         assert [User(name='chuck')] == sess.query(User).filter_by(addresses = None).all()
         assert [User(name='chuck')] == sess.query(User).filter_by(addresses = null()).all()
-    
+
     def test_none_comparison(self):
         sess = create_session()
-        
+
         # scalar
         eq_(
             [Order(description="order 5")],
@@ -914,7 +914,7 @@ class FilterTest(QueryTest):
             [Order(description="order 5")],
             sess.query(Order).filter(Order.address_id==null()).all()
         )
-        
+
         # o2o
         eq_([Address(id=1), Address(id=3), Address(id=4)], 
             sess.query(Address).filter(Address.dingaling==None).order_by(Address.id).all())
@@ -922,11 +922,11 @@ class FilterTest(QueryTest):
             sess.query(Address).filter(Address.dingaling==null()).order_by(Address.id).all())
         eq_([Address(id=2), Address(id=5)], sess.query(Address).filter(Address.dingaling != None).order_by(Address.id).all())
         eq_([Address(id=2), Address(id=5)], sess.query(Address).filter(Address.dingaling != null()).order_by(Address.id).all())
-        
+
         # m2o
         eq_([Order(id=5)], sess.query(Order).filter(Order.address==None).all())
         eq_([Order(id=1), Order(id=2), Order(id=3), Order(id=4)], sess.query(Order).order_by(Order.id).filter(Order.address!=None).all())
-        
+
         # o2m
         eq_([User(id=10)], sess.query(User).filter(User.addresses==None).all())
         eq_([User(id=7),User(id=8),User(id=9)], sess.query(User).filter(User.addresses!=None).order_by(User.id).all())
@@ -942,16 +942,16 @@ class FilterTest(QueryTest):
         )
 
 
-    
+
 class SetOpsTest(QueryTest, AssertsCompiledSQL):
-    
+
     def test_union(self):
         s = create_session()
-        
+
         fred = s.query(User).filter(User.name=='fred')
         ed = s.query(User).filter(User.name=='ed')
         jack = s.query(User).filter(User.name=='jack')
-        
+
         eq_(fred.union(ed).order_by(User.name).all(), 
             [User(name='ed'), User(name='fred')]
         )
@@ -959,17 +959,17 @@ class SetOpsTest(QueryTest, AssertsCompiledSQL):
         eq_(fred.union(ed, jack).order_by(User.name).all(), 
             [User(name='ed'), User(name='fred'), User(name='jack')]
         )
-    
+
     def test_statement_labels(self):
         """test that label conflicts don't occur with joins etc."""
-        
+
         s = create_session()
         q1 = s.query(User, Address).join(User.addresses).\
                                     filter(Address.email_address=="ed@wood.com")
         q2 = s.query(User, Address).join(User.addresses).\
                                     filter(Address.email_address=="jack@bean.com")
         q3 = q1.union(q2).order_by(User.name)
-        
+
         eq_(
             q3.all(),
             [
@@ -977,11 +977,11 @@ class SetOpsTest(QueryTest, AssertsCompiledSQL):
                 (User(name='jack'), Address(email_address="jack@bean.com")),
             ]
         )
-        
+
     def test_union_literal_expressions_compile(self):
         """test that column expressions translate during 
             the _from_statement() portion of union(), others"""
-        
+
         s = Session()
         q1 = s.query(User, literal("x"))
         q2 = s.query(User, literal_column("'y'"))
@@ -1011,7 +1011,7 @@ class SetOpsTest(QueryTest, AssertsCompiledSQL):
             [x['name'] for x in q6.column_descriptions],
             ['User', 'foo']
         )
-        
+
         for q in (q3.order_by(User.id, "anon_1_anon_2"), q6.order_by(User.id, "foo")):
             eq_(q.all(),
                 [
@@ -1025,15 +1025,15 @@ class SetOpsTest(QueryTest, AssertsCompiledSQL):
                     (User(id=10, name=u'chuck'), u'y')
                 ]
             )
-    
+
     def test_union_labeled_anonymous_columns(self):
         s = Session()
-        
+
         c1, c2 = column('c1'), column('c2')
         q1 = s.query(User, c1.label('foo'), c1.label('bar'))
         q2 = s.query(User, c1.label('foo'), c2.label('bar'))
         q3 = q1.union(q2)
-        
+
         eq_(
             [x['name'] for x in q3.column_descriptions],
             ['User', 'foo', 'bar']
@@ -1050,12 +1050,12 @@ class SetOpsTest(QueryTest, AssertsCompiledSQL):
             "FROM users) AS anon_1",
             use_default_dialect=True
         )
-    
+
     def test_union_mapped_colnames_preserved_across_subquery(self):
         s = Session()
         q1 = s.query(User.name)
         q2 = s.query(User.name)
-        
+
         # the label names in the subquery are the typical anonymized ones
         self.assert_compile(
             q1.union(q2),
@@ -1064,15 +1064,15 @@ class SetOpsTest(QueryTest, AssertsCompiledSQL):
             "UNION SELECT users.name AS users_name FROM users) AS anon_1",
             use_default_dialect=True
         )
-        
+
         # but in the returned named tuples,
         # due to [ticket:1942], this should be 'name', not 'users_name'
         eq_(
             [x['name'] for x in q1.union(q2).column_descriptions],
             ['name']
         )
-        
-        
+
+
     @testing.fails_on('mysql', "mysql doesn't support intersect")
     def test_intersect(self):
         s = create_session()
@@ -1087,7 +1087,7 @@ class SetOpsTest(QueryTest, AssertsCompiledSQL):
         eq_(fred.union(ed).intersect(ed.union(jack)).all(), 
             [User(name='ed')]
         )
-    
+
     def test_eager_load(self):
         s = create_session()
 
@@ -1104,8 +1104,8 @@ class SetOpsTest(QueryTest, AssertsCompiledSQL):
                 ]
             )
         self.assert_sql_count(testing.db, go, 1)
-        
-        
+
+
 class AggregateTest(QueryTest):
 
     def test_sum(self):
@@ -1127,7 +1127,7 @@ class AggregateTest(QueryTest):
 class CountTest(QueryTest):
     def test_basic(self):
         s = create_session()
-        
+
         eq_(s.query(User).count(), 4)
 
         eq_(s.query(User).filter(users.c.name.endswith('ed')).count(), 2)
@@ -1136,10 +1136,10 @@ class CountTest(QueryTest):
         s = create_session()
         q = s.query(User, Address)
         eq_(q.count(), 20)  # cartesian product
-        
+
         q = s.query(User, Address).join(User.addresses)
         eq_(q.count(), 5)
-    
+
     def test_nested(self):
         s = create_session()
         q = s.query(User, Address).limit(2)
@@ -1150,12 +1150,12 @@ class CountTest(QueryTest):
 
         q = s.query(User, Address).join(User.addresses).limit(100)
         eq_(q.count(), 5)
-    
+
     def test_cols(self):
         """test that column-based queries always nest."""
-        
+
         s = create_session()
-        
+
         q = s.query(func.count(distinct(User.name)))
         eq_(q.count(), 1)
 
@@ -1171,8 +1171,8 @@ class CountTest(QueryTest):
         q = s.query(Address.user_id)
         eq_(q.count(), 5)
         eq_(q.distinct().count(), 3)
-        
-        
+
+
 class DistinctTest(QueryTest):
     def test_basic(self):
         eq_(
@@ -1232,9 +1232,9 @@ class HintsTest(QueryTest, AssertsCompiledSQL):
     def test_hints(self):
         from sqlalchemy.dialects import mysql
         dialect = mysql.dialect()
-        
+
         sess = create_session()
-        
+
         self.assert_compile(
             sess.query(User).with_hint(User, 'USE INDEX (col1_index,col2_index)'),
             "SELECT users.id AS users_id, users.name AS users_name "
@@ -1248,7 +1248,7 @@ class HintsTest(QueryTest, AssertsCompiledSQL):
             "FROM users",
             dialect=dialect
         )
-        
+
         ualias = aliased(User)
         self.assert_compile(
             sess.query(User, ualias).with_hint(ualias, 'USE INDEX (col1_index,col2_index)').
@@ -1259,7 +1259,7 @@ class HintsTest(QueryTest, AssertsCompiledSQL):
             "ON users.id < users_1.id",
             dialect=dialect
         )
-    
+
 
 class TextTest(QueryTest):
     def test_fulltext(self):
@@ -1304,7 +1304,7 @@ class ParentTest(QueryTest):
 
         o = sess.query(Order).filter(with_parent(u1, User.orders)).all()
         assert [Order(description="order 1"), Order(description="order 3"), Order(description="order 5")] == o
-        
+
         # test generative criterion
         o = sess.query(Order).with_parent(u1).filter(orders.c.id>2).all()
         assert [Order(description="order 3"), Order(description="order 5")] == o
@@ -1335,7 +1335,7 @@ class ParentTest(QueryTest):
 
     def test_with_transient(self):
         sess = Session()
-        
+
         q = sess.query(User)
         u1 = q.filter_by(name='jack').one()
         utrans = User(id=u1.id)
@@ -1350,7 +1350,7 @@ class ParentTest(QueryTest):
             [Order(description="order 1"), Order(description="order 3"), Order(description="order 5")],
             o.all()
         )
-        
+
     def test_with_pending_autoflush(self):
         sess = Session()
 
@@ -1376,9 +1376,9 @@ class ParentTest(QueryTest):
             sess.query(User).with_parent(opending, 'user').one(),
             User(id=o1.user_id)
         )
-        
 
-        
+
+
 
 class SynonymTest(QueryTest):
 
@@ -1499,7 +1499,7 @@ class ImmediateTest(_fixtures.FixtureTest):
                         filter(User.id.in_([8, 9])).
                         order_by(User.id).
                         one)
-                        
+
 
     @testing.future
     def test_getslice(self):
@@ -1514,10 +1514,10 @@ class ImmediateTest(_fixtures.FixtureTest):
         eq_(sess.query(User.id).filter_by(id=0).scalar(), None)
         eq_(sess.query(User).filter_by(id=7).scalar(),
             sess.query(User).filter_by(id=7).one())
-        
+
         assert_raises(sa.orm.exc.MultipleResultsFound, sess.query(User).scalar)
         assert_raises(sa.orm.exc.MultipleResultsFound, sess.query(User.id, User.name).scalar)
-        
+
     @testing.resolve_artifact_names
     def test_value(self):
         sess = create_session()
@@ -1580,7 +1580,7 @@ class UpdateDeleteTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_illegal_operations(self):
         s = create_session()
-        
+
         for q, mname in (
             (s.query(User).limit(2), "limit"),
             (s.query(User).offset(2), "offset"),
@@ -1591,17 +1591,17 @@ class UpdateDeleteTest(_base.MappedTest):
         ):
             assert_raises_message(sa_exc.InvalidRequestError, r"Can't call Query.update\(\) when %s\(\) has been called" % mname, q.update, {'name':'ed'})
             assert_raises_message(sa_exc.InvalidRequestError, r"Can't call Query.delete\(\) when %s\(\) has been called" % mname, q.delete)
-            
-        
+
+
     @testing.resolve_artifact_names
     def test_delete(self):
         sess = create_session(bind=testing.db, autocommit=False)
-    
+
         john,jack,jill,jane = sess.query(User).order_by(User.id).all()
         sess.query(User).filter(or_(User.name == 'john', User.name == 'jill')).delete()
-    
+
         assert john not in sess and jill not in sess
-    
+
         eq_(sess.query(User).order_by(User.id).all(), [jack,jane])
 
     @testing.resolve_artifact_names
@@ -1631,53 +1631,53 @@ class UpdateDeleteTest(_base.MappedTest):
         assert john not in sess and jill not in sess
         sess.rollback()
         assert john in sess and jill in sess
-    
+
     @testing.resolve_artifact_names
     def test_delete_without_session_sync(self):
         sess = create_session(bind=testing.db, autocommit=False)
-    
+
         john,jack,jill,jane = sess.query(User).order_by(User.id).all()
         sess.query(User).filter(or_(User.name == 'john', User.name == 'jill')).delete(synchronize_session=False)
-    
+
         assert john in sess and jill in sess
-    
+
         eq_(sess.query(User).order_by(User.id).all(), [jack,jane])
 
     @testing.resolve_artifact_names
     def test_delete_with_fetch_strategy(self):
         sess = create_session(bind=testing.db, autocommit=False)
-    
+
         john,jack,jill,jane = sess.query(User).order_by(User.id).all()
         sess.query(User).filter(or_(User.name == 'john', User.name == 'jill')).delete(synchronize_session='fetch')
-    
+
         assert john not in sess and jill not in sess
-    
+
         eq_(sess.query(User).order_by(User.id).all(), [jack,jane])
 
     @testing.fails_on('mysql', 'FIXME: unknown')
     @testing.resolve_artifact_names
     def test_delete_invalid_evaluation(self):
         sess = create_session(bind=testing.db, autocommit=False)
-    
+
         john,jack,jill,jane = sess.query(User).order_by(User.id).all()
-    
+
         assert_raises(sa_exc.InvalidRequestError,
             sess.query(User).filter(User.name == select([func.max(User.name)])).delete, synchronize_session='evaluate'
         )
-        
+
         sess.query(User).filter(User.name == select([func.max(User.name)])).delete(synchronize_session='fetch')
-        
+
         assert john not in sess
-    
+
         eq_(sess.query(User).order_by(User.id).all(), [jack,jill,jane])
 
     @testing.resolve_artifact_names
     def test_update(self):
         sess = create_session(bind=testing.db, autocommit=False)
-    
+
         john,jack,jill,jane = sess.query(User).order_by(User.id).all()
         sess.query(User).filter(User.age > 29).update({'age': User.age - 10}, synchronize_session='evaluate')
-    
+
         eq_([john.age, jack.age, jill.age, jane.age], [25,37,29,27])
         eq_(sess.query(User.age).order_by(User.id).all(), zip([25,37,29,27]))
 
@@ -1702,7 +1702,7 @@ class UpdateDeleteTest(_base.MappedTest):
         )
         class Data(_base.ComparableEntity):
             pass
-        
+
         mapper(Data, data, properties={'cnt':data.c.counter})
         metadata.create_all()
         d1 = Data()
@@ -1713,12 +1713,12 @@ class UpdateDeleteTest(_base.MappedTest):
 
         sess.query(Data).update({Data.cnt:Data.cnt + 1})
         sess.flush()
-        
+
         eq_(d1.cnt, 1)
 
         sess.query(Data).update({Data.cnt:Data.cnt + 1}, 'fetch')
         sess.flush()
-        
+
         eq_(d1.cnt, 2)
         sess.close()
 
@@ -1738,19 +1738,19 @@ class UpdateDeleteTest(_base.MappedTest):
         sess = create_session(bind=testing.db, autocommit=False, autoflush=False)
 
         john,jack,jill,jane = sess.query(User).order_by(User.id).all()
-    
+
         john.age = 50
         jack.age = 37
-    
+
         # autoflush is false.  therefore our '50' and '37' are getting blown away by this operation.
-    
+
         sess.query(User).filter(User.age > 29).update({'age': User.age - 10}, synchronize_session='evaluate')
 
         for x in (john, jack, jill, jane):
             assert not sess.is_modified(x)
 
         eq_([john.age, jack.age, jill.age, jane.age], [25,37,29,27])
-    
+
         john.age = 25
         assert john in sess.dirty
         assert jack in sess.dirty
@@ -1780,16 +1780,16 @@ class UpdateDeleteTest(_base.MappedTest):
         assert jill not in sess.dirty
         assert sess.is_modified(john)
         assert not sess.is_modified(jack)
-    
-    
+
+
 
     @testing.resolve_artifact_names
     def test_update_with_expire_strategy(self):
         sess = create_session(bind=testing.db, autocommit=False)
-    
+
         john,jack,jill,jane = sess.query(User).order_by(User.id).all()
         sess.query(User).filter(User.age > 29).update({'age': User.age - 10}, synchronize_session='fetch')
-    
+
         eq_([john.age, jack.age, jill.age, jane.age], [25,37,29,27])
         eq_(sess.query(User.age).order_by(User.id).all(), zip([25,37,29,27]))
 
@@ -1847,23 +1847,23 @@ class UpdateDeleteTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_update_all(self):
         sess = create_session(bind=testing.db, autocommit=False)
-    
+
         john,jack,jill,jane = sess.query(User).order_by(User.id).all()
         sess.query(User).update({'age': 42}, synchronize_session='evaluate')
-    
+
         eq_([john.age, jack.age, jill.age, jane.age], [42,42,42,42])
         eq_(sess.query(User.age).order_by(User.id).all(), zip([42,42,42,42]))
 
     @testing.resolve_artifact_names
     def test_delete_all(self):
         sess = create_session(bind=testing.db, autocommit=False)
-    
+
         john,jack,jill,jane = sess.query(User).order_by(User.id).all()
         sess.query(User).delete(synchronize_session='evaluate')
-        
+
         assert not (john in sess or jack in sess or jill in sess or jane in sess)
         eq_(sess.query(User).count(), 0)
-        
+
 
 class StatementOptionsTest(QueryTest):
 
@@ -1892,13 +1892,13 @@ class StatementOptionsTest(QueryTest):
 
 class OptionsTest(QueryTest):
     """Test the _get_paths() method of PropertyOption."""
-    
+
     def _option_fixture(self, *arg):
         from sqlalchemy.orm import interfaces
         class Opt(interfaces.PropertyOption):
             pass
         return Opt(arg)
-    
+
     def _make_path(self, path):
         r = []
         for i, item in enumerate(path):
@@ -1907,39 +1907,39 @@ class OptionsTest(QueryTest):
                     item = class_mapper(item)
             r.append(item)
         return tuple(r)
-        
+
     def _assert_path_result(self, opt, q, paths, mappers):
         eq_(
             opt._get_paths(q, False),
             ([self._make_path(p) for p in paths], 
             [class_mapper(c) for c in mappers])
         )
-        
+
     def test_get_path_one_level_string(self):
         sess = Session()
         q = sess.query(User)
-        
+
         opt = self._option_fixture("addresses")
         self._assert_path_result(opt, q, [(User, 'addresses')], [User])
 
     def test_get_path_one_level_attribute(self):
         sess = Session()
         q = sess.query(User)
-        
+
         opt = self._option_fixture(User.addresses)
         self._assert_path_result(opt, q, [(User, 'addresses')], [User])
 
     def test_get_path_one_level_with_unrelated(self):
         sess = Session()
         q = sess.query(Order)
-        
+
         opt = self._option_fixture("addresses")
         self._assert_path_result(opt, q, [], [])
 
     def test_path_multilevel_string(self):
         sess = Session()
         q = sess.query(User)
-        
+
         opt = self._option_fixture("orders.items.keywords")
         self._assert_path_result(opt, q, [
             (User, 'orders'), 
@@ -1951,7 +1951,7 @@ class OptionsTest(QueryTest):
     def test_path_multilevel_attribute(self):
         sess = Session()
         q = sess.query(User)
-        
+
         opt = self._option_fixture(User.orders, Order.items, Item.keywords)
         self._assert_path_result(opt, q, [
             (User, 'orders'), 
@@ -2013,10 +2013,10 @@ class OptionsTest(QueryTest):
         mapper(SubAddr, inherits=Address, properties={
             'flub':relationship(Dingaling)
         })
-        
+
         q = sess.query(Address)
         opt = self._option_fixture(SubAddr.flub)
-        
+
         self._assert_path_result(opt, q, [(Address, 'flub')], [SubAddr])
 
     def test_from_subclass_to_subclass_attr(self):
@@ -2026,10 +2026,10 @@ class OptionsTest(QueryTest):
         mapper(SubAddr, inherits=Address, properties={
             'flub':relationship(Dingaling)
         })
-        
+
         q = sess.query(SubAddr)
         opt = self._option_fixture(SubAddr.flub)
-        
+
         self._assert_path_result(opt, q, [(SubAddr, 'flub')], [SubAddr])
 
     def test_from_base_to_base_attr_via_subclass(self):
@@ -2039,10 +2039,10 @@ class OptionsTest(QueryTest):
         mapper(SubAddr, inherits=Address, properties={
             'flub':relationship(Dingaling)
         })
-        
+
         q = sess.query(Address)
         opt = self._option_fixture(SubAddr.user)
-        
+
         self._assert_path_result(opt, q, [(Address, 'user')], [Address])
 
     def test_of_type(self):
@@ -2050,10 +2050,10 @@ class OptionsTest(QueryTest):
         class SubAddr(Address):
             pass
         mapper(SubAddr, inherits=Address)
-        
+
         q = sess.query(User)
         opt = self._option_fixture(User.addresses.of_type(SubAddr), SubAddr.user)
-        
+
         self._assert_path_result(opt, q, [
             (User, 'addresses'),
             (User, 'addresses', SubAddr, 'user')
@@ -2066,15 +2066,15 @@ class OptionsTest(QueryTest):
         mapper(SubAddr, inherits=Address, properties={
             'flub':relationship(Dingaling)
         })
-        
+
         q = sess.query(User)
         opt = self._option_fixture(User.addresses.of_type(SubAddr), SubAddr.flub)
-        
+
         self._assert_path_result(opt, q, [
             (User, 'addresses'),
             (User, 'addresses', SubAddr, 'flub')
         ], [User, SubAddr])
-        
+
     def test_aliased_single(self):
         sess = Session()
         ualias = aliased(User)
@@ -2109,4 +2109,4 @@ class OptionsTest(QueryTest):
                 )
         opt = self._option_fixture(Address.user, User.addresses)
         self._assert_path_result(opt, q, [], [])
-        
+
index 39480d79fd30e8560de9e53f68b34813c1e83695..feb5c850368ccb40d9f1ba342912c339b430f924 100644 (file)
@@ -103,22 +103,22 @@ class CompositeSelfRefFKTest(_base.MappedTest):
     """Tests a composite FK where, in
     the relationship(), one col points 
     to itself in the same table.
-    
+
     this is a very unusual case::
-    
+
     company         employee
     ----------      ----------
     company_id <--- company_id ------+
     name                ^            |
                         +------------+
-                      
+
                     emp_id <---------+
                     name             |
                     reports_to_id ---+
-    
+
     employee joins to its sub-employees
     both on reports_to_id, *and on company_id to itself*.
-    
+
     """
 
     @classmethod
@@ -151,7 +151,7 @@ class CompositeSelfRefFKTest(_base.MappedTest):
                 self.company = company
                 self.emp_id = emp_id
                 self.reports_to = reports_to
-        
+
     @testing.resolve_artifact_names
     def test_explicit(self):
         mapper(Company, company_t)
@@ -198,7 +198,7 @@ class CompositeSelfRefFKTest(_base.MappedTest):
         })
 
         self._test()
-    
+
     @testing.resolve_artifact_names
     def test_very_explicit(self):
         mapper(Company, company_t)
@@ -215,7 +215,7 @@ class CompositeSelfRefFKTest(_base.MappedTest):
         })
 
         self._test()
-        
+
     @testing.resolve_artifact_names
     def _test(self):
         sess = create_session()
@@ -398,7 +398,7 @@ class FKsAsPksTest(_base.MappedTest):
                             test_needs_autoincrement=True),
               Column("foo",Integer,),
               test_needs_fk=True)
-              
+
         Table("tableB",metadata,
               Column("id",Integer,ForeignKey("tableA.id"),primary_key=True),
               test_needs_fk=True)
@@ -415,16 +415,16 @@ class FKsAsPksTest(_base.MappedTest):
     def test_onetoone_switch(self):
         """test that active history is enabled on a 
         one-to-many/one that has use_get==True"""
-        
+
         mapper(A, tableA, properties={
             'b':relationship(B, cascade="all,delete-orphan", uselist=False)})
         mapper(B, tableB)
-        
+
         configure_mappers()
         assert A.b.property.strategy.use_get
-        
+
         sess = create_session()
-        
+
         a1 = A()
         sess.add(a1)
         sess.flush()
@@ -432,7 +432,7 @@ class FKsAsPksTest(_base.MappedTest):
         a1 = sess.query(A).first()
         a1.b = B()
         sess.flush()
-        
+
     @testing.resolve_artifact_names
     def test_no_delete_PK_AtoB(self):
         """A cant be deleted without B because B would have no PK value."""
@@ -531,7 +531,7 @@ class FKsAsPksTest(_base.MappedTest):
     def test_delete_cascade_AtoB(self):
         """No 'blank the PK' error when the child is to 
         be deleted as part of a cascade"""
-        
+
         for cascade in ("save-update, delete",
                         #"save-update, delete-orphan",
                         "save-update, delete, delete-orphan"):
@@ -597,7 +597,7 @@ class FKsAsPksTest(_base.MappedTest):
 class UniqueColReferenceSwitchTest(_base.MappedTest):
     """test a relationship based on a primary 
     join against a unique non-pk column"""
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table("table_a", metadata,
@@ -614,7 +614,7 @@ class UniqueColReferenceSwitchTest(_base.MappedTest):
                                         ForeignKey('table_a.ident'), 
                                         nullable=False),
                         )
-    
+
     @classmethod
     def setup_classes(cls):
         class A(_base.ComparableEntity):
@@ -641,7 +641,7 @@ class UniqueColReferenceSwitchTest(_base.MappedTest):
             b.a = a2
         session.delete(a1)
         session.flush()
-    
+
 class RelationshipToSelectableTest(_base.MappedTest):
     """Test a map to a select that relates to a map to the table."""
 
@@ -712,9 +712,9 @@ class FKEquatedToConstantTest(_base.MappedTest):
     """test a relationship with a non-column entity in the primary join, 
     is not viewonly, and also has the non-column's clause mentioned in the 
     foreign keys list.
-    
+
     """
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('tags', metadata, Column("id", Integer, primary_key=True, 
@@ -753,13 +753,13 @@ class FKEquatedToConstantTest(_base.MappedTest):
         sess.add(t1)
         sess.flush()
         sess.expunge_all()
-        
+
         # relationship works
         eq_(
             sess.query(Tag).all(), 
             [Tag(data='some tag', foo=[TagInstance(data='iplc_case')])]
         )
-        
+
         # both TagInstances were persisted
         eq_(
             sess.query(TagInstance).order_by(TagInstance.data).all(), 
@@ -767,7 +767,7 @@ class FKEquatedToConstantTest(_base.MappedTest):
         )
 
 class BackrefPropagatesForwardsArgs(_base.MappedTest):
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('users', metadata, 
@@ -781,17 +781,17 @@ class BackrefPropagatesForwardsArgs(_base.MappedTest):
             Column('user_id', Integer),
             Column('email', String(50))
         )
-    
+
     @classmethod
     def setup_classes(cls):
         class User(_base.ComparableEntity):
             pass
         class Address(_base.ComparableEntity):
             pass
-    
+
     @testing.resolve_artifact_names
     def test_backref(self):
-        
+
         mapper(User, users, properties={
             'addresses':relationship(Address, 
                         primaryjoin=addresses.c.user_id==users.c.id, 
@@ -799,7 +799,7 @@ class BackrefPropagatesForwardsArgs(_base.MappedTest):
                         backref='user')
         })
         mapper(Address, addresses)
-        
+
         sess = sessionmaker()()
         u1 = User(name='u1', addresses=[Address(email='a1')])
         sess.add(u1)
@@ -807,18 +807,18 @@ class BackrefPropagatesForwardsArgs(_base.MappedTest):
         eq_(sess.query(Address).all(), [
             Address(email='a1', user=User(name='u1'))
         ])
-    
+
 class AmbiguousJoinInterpretedAsSelfRef(_base.MappedTest):
     """test ambiguous joins due to FKs on both sides treated as
     self-referential.
-    
+
     this mapping is very similar to that of
     test/orm/inheritance/query.py
     SelfReferentialTestJoinedToBase , except that inheritance is
     not used here.
-    
+
     """
-    
+
     @classmethod
     def define_tables(cls, metadata):
         subscriber_table = Table('subscriber', metadata,
@@ -854,14 +854,14 @@ class AmbiguousJoinInterpretedAsSelfRef(_base.MappedTest):
            'addresses' : relationship(Address, 
                 backref=backref("customer"))
            })
-        
+
     @testing.resolve_artifact_names
     def test_mapping(self):
         from sqlalchemy.orm.interfaces import ONETOMANY, MANYTOONE
         sess = create_session()
         assert Subscriber.addresses.property.direction is ONETOMANY
         assert Address.customer.property.direction is MANYTOONE
-        
+
         s1 = Subscriber(type='A',
                 addresses = [
                     Address(type='D'),
@@ -869,15 +869,15 @@ class AmbiguousJoinInterpretedAsSelfRef(_base.MappedTest):
                 ]
         )
         a1 = Address(type='B', customer=Subscriber(type='C'))
-        
+
         assert s1.addresses[0].customer is s1
         assert a1.customer.addresses[0] is a1
-        
+
         sess.add_all([s1, a1])
-        
+
         sess.flush()
         sess.expunge_all()
-        
+
         eq_(
             sess.query(Subscriber).order_by(Subscriber.type).all(),
             [
@@ -892,24 +892,24 @@ class ManualBackrefTest(_fixtures.FixtureTest):
     """Test explicit relationships that are backrefs to each other."""
 
     run_inserts = None
-    
+
     @testing.resolve_artifact_names
     def test_o2m(self):
         mapper(User, users, properties={
             'addresses':relationship(Address, back_populates='user')
         })
-        
+
         mapper(Address, addresses, properties={
             'user':relationship(User, back_populates='addresses')
         })
-        
+
         sess = create_session()
-        
+
         u1 = User(name='u1')
         a1 = Address(email_address='foo')
         u1.addresses.append(a1)
         assert a1.user is u1
-        
+
         sess.add(u1)
         sess.flush()
         sess.expire_all()
@@ -922,33 +922,33 @@ class ManualBackrefTest(_fixtures.FixtureTest):
         mapper(User, users, properties={
             'addresses':relationship(Address, back_populates='userr')
         })
-        
+
         mapper(Address, addresses, properties={
             'user':relationship(User, back_populates='addresses')
         })
-        
+
         assert_raises(sa.exc.InvalidRequestError, configure_mappers)
-        
+
     @testing.resolve_artifact_names
     def test_invalid_target(self):
         mapper(User, users, properties={
             'addresses':relationship(Address, back_populates='dingaling'),
         })
-        
+
         mapper(Dingaling, dingalings)
         mapper(Address, addresses, properties={
             'dingaling':relationship(Dingaling)
         })
-        
+
         assert_raises_message(sa.exc.ArgumentError, 
             r"reverse_property 'dingaling' on relationship "
             "User.addresses references "
             "relationship Address.dingaling, which does not "
             "reference mapper Mapper\|User\|users", 
             configure_mappers)
-        
+
 class JoinConditionErrorTest(testing.TestBase):
-    
+
     def test_clauseelement_pj(self):
         from sqlalchemy.ext.declarative import declarative_base
         Base = declarative_base()
@@ -960,7 +960,7 @@ class JoinConditionErrorTest(testing.TestBase):
             id = Column('id', Integer, primary_key=True)
             c1id = Column('c1id', Integer, ForeignKey('c1.id'))
             c2 = relationship(C1, primaryjoin=C1.id)
-        
+
         assert_raises(sa.exc.ArgumentError, configure_mappers)
 
     def test_clauseelement_pj_false(self):
@@ -976,7 +976,7 @@ class JoinConditionErrorTest(testing.TestBase):
             c2 = relationship(C1, primaryjoin="x"=="y")
 
         assert_raises(sa.exc.ArgumentError, configure_mappers)
-    
+
     def test_only_column_elements(self):
         m = MetaData()
         t1 = Table('t1', m, 
@@ -991,15 +991,15 @@ class JoinConditionErrorTest(testing.TestBase):
         class C2(object):
             pass
 
-        mapper(C1, t1, properties={'c2':relationship(C2,  
+        mapper(C1, t1, properties={'c2':relationship(C2,
                                             primaryjoin=t1.join(t2))})
         mapper(C2, t2)
         assert_raises(sa.exc.ArgumentError, configure_mappers)
-    
+
     def test_invalid_string_args(self):
         from sqlalchemy.ext.declarative import declarative_base
         from sqlalchemy import util
-        
+
         for argname, arg in [
             ('remote_side', ['c1.id']),
             ('remote_side', ['id']),
@@ -1013,21 +1013,21 @@ class JoinConditionErrorTest(testing.TestBase):
             class C1(Base):
                 __tablename__ = 'c1'
                 id = Column('id', Integer, primary_key=True)
-            
+
             class C2(Base):
                 __tablename__ = 'c2'
                 id_ = Column('id', Integer, primary_key=True)
                 c1id = Column('c1id', Integer, ForeignKey('c1.id'))
                 c2 = relationship(C1, **kw)
-            
+
             assert_raises_message(
                 sa.exc.ArgumentError, 
                 "Column-based expression object expected "
                 "for argument '%s'; got: '%s', type %r" % 
                 (argname, arg[0], type(arg[0])),
                 configure_mappers)
-        
-    
+
+
     def test_fk_error_raised(self):
         m = MetaData()
         t1 = Table('t1', m, 
@@ -1042,17 +1042,17 @@ class JoinConditionErrorTest(testing.TestBase):
             Column('id', Integer, primary_key=True),
             Column('t1id', Integer, ForeignKey('t1.id'))
         )
-        
+
         class C1(object):
             pass
         class C2(object):
             pass
-        
+
         mapper(C1, t1, properties={'c2':relationship(C2)})
         mapper(C2, t3)
-        
+
         assert_raises(sa.exc.NoReferencedColumnError, configure_mappers)
-    
+
     def test_join_error_raised(self):
         m = MetaData()
         t1 = Table('t1', m, 
@@ -1076,10 +1076,10 @@ class JoinConditionErrorTest(testing.TestBase):
         mapper(C2, t3)
 
         assert_raises(sa.exc.ArgumentError, configure_mappers)
-    
+
     def teardown(self):
-        clear_mappers()    
-        
+        clear_mappers()
+
 class TypeMatchTest(_base.MappedTest):
     """test errors raised when trying to add items 
         whose type is not handled by a relationship"""
@@ -1273,18 +1273,18 @@ class ViewOnlyM2MBackrefTest(_base.MappedTest):
             Column('t1id', Integer, ForeignKey('t1.id'), primary_key=True),
             Column('t2id', Integer, ForeignKey('t2.id'), primary_key=True),
         )
-    
+
     @testing.resolve_artifact_names
     def test_viewonly(self):
         class A(_base.ComparableEntity):pass
         class B(_base.ComparableEntity):pass
-        
+
         mapper(A, t1, properties={
             'bs':relationship(B, secondary=t1t2, 
                                 backref=backref('as_', viewonly=True))
         })
         mapper(B, t2)
-        
+
         sess = create_session()
         a1 = A()
         b1 = B(as_=[a1])
@@ -1297,7 +1297,7 @@ class ViewOnlyM2MBackrefTest(_base.MappedTest):
         eq_(
             sess.query(B).first(), B(as_=[A(id=a1.id)])
         )
-        
+
 class ViewOnlyOverlappingNames(_base.MappedTest):
     """'viewonly' mappings with overlapping PK column names."""
 
@@ -1425,10 +1425,10 @@ class ViewOnlyUniqueNames(_base.MappedTest):
 
 class ViewOnlyLocalRemoteM2M(testing.TestBase):
     """test that local-remote is correctly determined for m2m"""
-    
+
     def test_local_remote(self):
         meta = MetaData()
-        
+
         t1 = Table('t1', meta,
                 Column('id', Integer, primary_key=True),
             )
@@ -1439,7 +1439,7 @@ class ViewOnlyLocalRemoteM2M(testing.TestBase):
                 Column('t1_id', Integer, ForeignKey('t1.id',)),
                 Column('t2_id', Integer, ForeignKey('t2.id',)),
             )
-        
+
         class A(object): pass
         class B(object): pass
         mapper( B, t2, )
@@ -1453,8 +1453,8 @@ class ViewOnlyLocalRemoteM2M(testing.TestBase):
             m.get_property('b_plain').local_remote_pairs == \
             [(t1.c.id, t12.c.t1_id), (t2.c.id, t12.c.t2_id)]
 
-        
-    
+
+
 class ViewOnlyNonEquijoin(_base.MappedTest):
     """'viewonly' mappings based on non-equijoins."""
 
@@ -1878,7 +1878,7 @@ class InvalidRemoteSideTest(_base.MappedTest):
             "mean to set remote_side on the many-to-one side ?", 
             configure_mappers)
 
-        
+
 class InvalidRelationshipEscalationTest(_base.MappedTest):
 
     @classmethod
@@ -2041,8 +2041,8 @@ class InvalidRelationshipEscalationTest(_base.MappedTest):
             sa.exc.ArgumentError, 
                 "could not determine any local/remote column pairs",
                 sa.orm.configure_mappers)
-        
-    
+
+
     @testing.resolve_artifact_names
     def test_no_equated_self_ref(self):
         mapper(Foo, foos, properties={
@@ -2093,7 +2093,7 @@ class InvalidRelationshipEscalationTest(_base.MappedTest):
                         viewonly=True)})
         mapper(Bar, bars_with_fks)
         sa.orm.configure_mappers()
-        
+
     @testing.resolve_artifact_names
     def test_no_equated_self_ref_viewonly(self):
         mapper(Foo, foos, properties={
@@ -2111,7 +2111,7 @@ class InvalidRelationshipEscalationTest(_base.MappedTest):
                               "present, or are otherwise part of a "
                               "ForeignKeyConstraint on their parent "
                               "Table.", sa.orm.configure_mappers)
-        
+
         sa.orm.clear_mappers()
         mapper(Foo, foos_with_fks, properties={
           'foos':relationship(Foo,
@@ -2162,7 +2162,7 @@ class InvalidRelationshipEscalationTest(_base.MappedTest):
             "Could not determine relationship direction for primaryjoin "
             "condition",
             configure_mappers)
-        
+
 
     @testing.resolve_artifact_names
     def test_equated_self_ref_wrong_fks(self):
@@ -2243,7 +2243,7 @@ class InvalidRelationshipEscalationTestM2M(_base.MappedTest):
                                 primaryjoin=foos.c.id==foobars.c.fid,
                                 secondaryjoin=foobars.c.bid==bars.c.id)})
         mapper(Bar, bars)
-        
+
         assert_raises_message(sa.exc.SAWarning,
                               "No ForeignKey objects were present in "
                               "secondary table 'foobars'.  Assumed "
@@ -2252,7 +2252,7 @@ class InvalidRelationshipEscalationTestM2M(_base.MappedTest):
                               "condition 'foos.id = foobars.fid' on "
                               "relationship Foo.bars",
                               sa.orm.configure_mappers)
-        
+
         sa.orm.clear_mappers()
         mapper(Foo, foos, properties={
                         'bars': relationship(Bar, 
@@ -2314,8 +2314,8 @@ class InvalidRelationshipEscalationTestM2M(_base.MappedTest):
             Foo.bars.property.secondary_synchronize_pairs,
             [(bars.c.id, foobars_with_many_columns.c.bid)]
         )
-        
-        
+
+
     @testing.resolve_artifact_names
     def test_bad_primaryjoin(self):
         mapper(Foo, foos, properties={
@@ -2330,7 +2330,7 @@ class InvalidRelationshipEscalationTestM2M(_base.MappedTest):
             "Could not determine relationship direction for "
             "primaryjoin condition",
             configure_mappers)
-    
+
         sa.orm.clear_mappers()
         mapper(Foo, foos, properties={
             'bars': relationship(Bar,
@@ -2360,7 +2360,7 @@ class InvalidRelationshipEscalationTestM2M(_base.MappedTest):
                              viewonly=True)})
         mapper(Bar, bars)
         sa.orm.configure_mappers()
-        
+
     @testing.resolve_artifact_names
     def test_bad_secondaryjoin(self):
         mapper(Foo, foos, properties={
@@ -2404,22 +2404,22 @@ class InvalidRelationshipEscalationTestM2M(_base.MappedTest):
 class ActiveHistoryFlagTest(_fixtures.FixtureTest):
     run_inserts = None
     run_deletes = None
-    
+
     def _test_attribute(self, obj, attrname, newvalue):
         sess = Session()
         sess.add(obj)
         oldvalue = getattr(obj, attrname)
         sess.commit()
-        
+
         # expired
         assert attrname not in obj.__dict__
-        
+
         setattr(obj, attrname, newvalue)
         eq_(
             attributes.get_history(obj, attrname),
             ([newvalue,], (), [oldvalue,])
         )
-    
+
     @testing.resolve_artifact_names
     def test_column_property_flag(self):
         mapper(User, users, properties={
@@ -2439,7 +2439,7 @@ class ActiveHistoryFlagTest(_fixtures.FixtureTest):
         u2 = User(name='ed')
         a1 = Address(email_address='a1', user=u1)
         self._test_attribute(a1, 'user', u2)
-    
+
     @testing.resolve_artifact_names
     def test_composite_property_flag(self):
         class MyComposite(object):
@@ -2460,12 +2460,12 @@ class ActiveHistoryFlagTest(_fixtures.FixtureTest):
         })
         o1 = Order(composite=MyComposite('foo', 1))
         self._test_attribute(o1, "composite", MyComposite('bar', 1))
-        
-    
+
+
 
 class RelationDeprecationTest(_base.MappedTest):
     """test usage of the old 'relation' function."""
-    
+
     run_inserts = 'once'
     run_deletes = None
 
index 43472eae3da3fe4dab01d3992e9314f903b2e896..2ea1960f16f9da00578e0255be28ac064e4cf1ee 100644 (file)
@@ -78,7 +78,7 @@ class ScopedSessionTest(_base.MappedTest):
 
     def test_config_errors(self):
         Session = scoped_session(sa.orm.sessionmaker())
-    
+
         s = Session()
         assert_raises_message(
             sa.exc.InvalidRequestError,
@@ -91,6 +91,6 @@ class ScopedSessionTest(_base.MappedTest):
             "At least one scoped session is already present. ",
             Session.configure, bind=testing.db
         )
-        
+
 
 
index 54d0980a02a0d27748b407de92ac9725162b13c9..d1cf29751a5cf1a53c5a0e8f2088f7b5a9e1bffc 100644 (file)
@@ -46,12 +46,12 @@ class SelectableNoFromsTest(_base.MappedTest, AssertsCompiledSQL):
             "could not assemble any primary key columns",
             mapper, Subset, selectable
         )
-        
+
     @testing.resolve_artifact_names
     def test_no_selects(self):
         subset_select = select([common.c.id, common.c.data])
         assert_raises(sa.exc.InvalidRequestError, mapper, Subset, subset_select)
-        
+
     @testing.resolve_artifact_names
     def test_basic(self):
         subset_select = select([common.c.id, common.c.data]).alias()
index d8b9b073ab9ec80028b2ed667c0d01fe27057360..ab0251368e2af67d1be4585d641d34488aa647c4 100644 (file)
@@ -78,7 +78,7 @@ class SessionTest(_fixtures.FixtureTest):
             object_session, 
             User()
         )
-        
+
     @testing.requires.sequences
     def test_sequence_execute(self):
         seq = Sequence("some_sequence")
@@ -88,8 +88,8 @@ class SessionTest(_fixtures.FixtureTest):
             eq_(sess.execute(seq), 1)
         finally:
             seq.drop(testing.db)
-        
-        
+
+
     @testing.resolve_artifact_names
     def test_expunge_cascade(self):
         mapper(Address, addresses)
@@ -152,7 +152,7 @@ class SessionTest(_fixtures.FixtureTest):
 
         sess.execute(users_unbound.delete())
         eq_(sess.execute(users_unbound.select()).fetchall(), [])
-        
+
         sess.close()
 
     @engines.close_open_connections
@@ -256,7 +256,7 @@ class SessionTest(_fixtures.FixtureTest):
         sess = create_session()
         sess.add(User(name='test'))
         sess.flush()
-        
+
         u1 = sess.query(User).first()
         make_transient(u1)
         assert u1 not in sess
@@ -268,7 +268,7 @@ class SessionTest(_fixtures.FixtureTest):
         make_transient(u1)
         sess.add(u1)
         assert u1 in sess.new
-        
+
         # test expired attributes 
         # get unexpired
         u1 = sess.query(User).first()
@@ -279,9 +279,9 @@ class SessionTest(_fixtures.FixtureTest):
 
         # works twice
         make_transient(u1)
-        
+
         sess.close()
-        
+
         u1.name = 'test2'
         sess.add(u1)
         sess.flush()
@@ -289,7 +289,7 @@ class SessionTest(_fixtures.FixtureTest):
         sess.delete(u1)
         sess.flush()
         assert u1 not in sess
-        
+
         assert_raises(sa.exc.InvalidRequestError, sess.add, u1)
         make_transient(u1)
         sess.add(u1)
@@ -299,37 +299,37 @@ class SessionTest(_fixtures.FixtureTest):
     @testing.resolve_artifact_names
     def test_deleted_flag(self):
         mapper(User, users)
-        
+
         sess = sessionmaker()()
-        
+
         u1 = User(name='u1')
         sess.add(u1)
         sess.commit()
-        
+
         sess.delete(u1)
         sess.flush()
         assert u1 not in sess
         assert_raises(sa.exc.InvalidRequestError, sess.add, u1)
         sess.rollback()
         assert u1 in sess
-        
+
         sess.delete(u1)
         sess.commit()
         assert u1 not in sess
         assert_raises(sa.exc.InvalidRequestError, sess.add, u1)
-        
+
         make_transient(u1)
         sess.add(u1)
         sess.commit()
-        
+
         eq_(sess.query(User).count(), 1)
-        
+
     @testing.resolve_artifact_names
     def test_autoflush_expressions(self):
         """test that an expression which is dependent on object state is 
         evaluated after the session autoflushes.   This is the lambda
         inside of strategies.py lazy_clause.
-        
+
         """
         mapper(User, users, properties={
             'addresses':relationship(Address, backref="user")})
@@ -419,7 +419,7 @@ class SessionTest(_fixtures.FixtureTest):
         assert newad not in u.addresses
         # pending objects dont get expired
         assert newad.email_address == 'a new address'
-    
+
     @testing.resolve_artifact_names
     def test_autocommit_doesnt_raise_on_pending(self):
         mapper(User, users)
@@ -430,7 +430,7 @@ class SessionTest(_fixtures.FixtureTest):
         session.begin()
         session.flush()
         session.commit()
-    
+
     def test_active_flag(self):
         sess = create_session(bind=config.db, autocommit=True)
         assert not sess.is_active
@@ -438,7 +438,7 @@ class SessionTest(_fixtures.FixtureTest):
         assert sess.is_active
         sess.rollback()
         assert not sess.is_active
-        
+
     @testing.resolve_artifact_names
     def test_textual_execute(self):
         """test that Session.execute() converts to text()"""
@@ -525,15 +525,15 @@ class SessionTest(_fixtures.FixtureTest):
     def test_transactions_isolated(self):
         mapper(User, users)
         users.delete().execute()
-        
+
         s1 = create_session(bind=testing.db, autocommit=False)
         s2 = create_session(bind=testing.db, autocommit=False)
         u1 = User(name='u1')
         s1.add(u1)
         s1.flush()
-        
+
         assert s2.query(User).all() == []
-        
+
     @testing.requires.two_phase_transactions
     @testing.resolve_artifact_names
     def test_twophase(self):
@@ -727,7 +727,7 @@ class SessionTest(_fixtures.FixtureTest):
             sa.exc.DBAPIError,
             sess.commit
         )
-        
+
         for i in range(5):
             assert_raises_message(sa.exc.InvalidRequestError,
                               "^This Session's transaction has been "
@@ -740,8 +740,8 @@ class SessionTest(_fixtures.FixtureTest):
         sess.rollback()
         sess.add(User(id=5, name='some name'))
         sess.commit()
-        
-        
+
+
     @testing.resolve_artifact_names
     def test_no_autocommit_with_explicit_commit(self):
         mapper(User, users)
@@ -861,7 +861,7 @@ class SessionTest(_fixtures.FixtureTest):
         assert user not in s
         s.delete(user)
         assert user in s
-        
+
         s.flush()
         assert user not in s
         assert s.query(User).count() == 0
@@ -959,17 +959,17 @@ class SessionTest(_fixtures.FixtureTest):
 
         del user
         s.add(u2)
-        
+
         del u2
         gc_collect()
-        
+
         assert len(s.identity_map) == 1
         assert len(s.dirty) == 1
         assert None not in s.dirty
         s.flush()
         gc_collect()
         assert not s.dirty
-        
+
         assert not s.identity_map
 
     @testing.resolve_artifact_names
@@ -990,8 +990,8 @@ class SessionTest(_fixtures.FixtureTest):
 
             assert_raises(AssertionError, s.identity_map.add,
                           sa.orm.attributes.instance_state(u2))
-        
-        
+
+
     @testing.resolve_artifact_names
     def test_weakref_with_cycles_o2m(self):
         s = sessionmaker()()
@@ -1001,11 +1001,11 @@ class SessionTest(_fixtures.FixtureTest):
         mapper(Address, addresses)
         s.add(User(name="ed", addresses=[Address(email_address="ed1")]))
         s.commit()
-        
+
         user = s.query(User).options(joinedload(User.addresses)).one()
         user.addresses[0].user # lazyload
         eq_(user, User(name="ed", addresses=[Address(email_address="ed1")]))
-        
+
         del user
         gc_collect()
         assert len(s.identity_map) == 0
@@ -1016,11 +1016,11 @@ class SessionTest(_fixtures.FixtureTest):
         del user
         gc_collect()
         assert len(s.identity_map) == 2
-        
+
         s.commit()
         user = s.query(User).options(joinedload(User.addresses)).one()
         eq_(user, User(name="ed", addresses=[Address(email_address="ed2")]))
-        
+
     @testing.resolve_artifact_names
     def test_weakref_with_cycles_o2o(self):
         s = sessionmaker()()
@@ -1046,11 +1046,11 @@ class SessionTest(_fixtures.FixtureTest):
         del user
         gc_collect()
         assert len(s.identity_map) == 2
-        
+
         s.commit()
         user = s.query(User).options(joinedload(User.address)).one()
         eq_(user, User(name="ed", address=Address(email_address="ed2")))
-    
+
     @testing.resolve_artifact_names
     def test_strong_ref(self):
         s = create_session(weak_identity_map=False)
@@ -1071,7 +1071,7 @@ class SessionTest(_fixtures.FixtureTest):
         assert s.identity_map._modified
         s.flush()
         eq_(users.select().execute().fetchall(), [(user.id, 'u2')])
-        
+
     @testing.fails_on('+zxjdbc', 'http://www.sqlalchemy.org/trac/ticket/1473')
     @testing.resolve_artifact_names
     def test_prune(self):
@@ -1198,10 +1198,10 @@ class SessionTest(_fixtures.FixtureTest):
         mapper(User, users)
 
         sess = Session()
-        
+
         sess.add_all([User(name='u1'), User(name='u2'), User(name='u3')])
         sess.commit()
-        
+
         u1, u2, u3 = sess.query(User).all()
         for i, (key, value) in enumerate(sess.identity_map.iteritems()):
             if i == 2:
@@ -1212,7 +1212,7 @@ class DisposedStates(_base.MappedTest):
     run_setup_mappers = 'once'
     run_inserts = 'once'
     run_deletes = None
-    
+
     @classmethod
     def define_tables(cls, metadata):
         global t1
@@ -1227,25 +1227,25 @@ class DisposedStates(_base.MappedTest):
             def __init__(self, data):
                 self.data = data
         mapper(T, t1)
-    
+
     def teardown(self):
         from sqlalchemy.orm.session import _sessions
         _sessions.clear()
         super(DisposedStates, self).teardown()
-        
+
     def _set_imap_in_disposal(self, sess, *objs):
         """remove selected objects from the given session, as though
         they were dereferenced and removed from WeakIdentityMap.
-        
+
         Hardcodes the identity map's "all_states()" method to return the
         full list of states.  This simulates the all_states() method
         returning results, afterwhich some of the states get garbage
         collected (this normally only happens during asynchronous gc).
         The Session now has one or more InstanceState's which have been
         removed from the identity map and disposed.
-        
+
         Will the Session not trip over this ???  Stay tuned.
-        
+
         """
 
         all_states = sess.identity_map.all_states()
@@ -1254,7 +1254,7 @@ class DisposedStates(_base.MappedTest):
             state = attributes.instance_state(obj)
             sess.identity_map.remove(state)
             state.dispose()
-    
+
     def _test_session(self, **kwargs):
         global sess
         sess = create_session(**kwargs)
@@ -1268,32 +1268,32 @@ class DisposedStates(_base.MappedTest):
 
         o1.data = 't1modified'
         o5.data = 't5modified'
-        
+
         self._set_imap_in_disposal(sess, o2, o4, o5)
         return sess
-        
+
     def test_flush(self):
         self._test_session().flush()
-    
+
     def test_clear(self):
         self._test_session().expunge_all()
-    
+
     def test_close(self):
         self._test_session().close()
-        
+
     def test_expunge_all(self):
         self._test_session().expunge_all()
-        
+
     def test_expire_all(self):
         self._test_session().expire_all()
-    
+
     def test_rollback(self):
         sess = self._test_session(autocommit=False, expire_on_commit=True)
         sess.commit()
-        
+
         sess.rollback()
-        
-        
+
+
 class SessionInterface(testing.TestBase):
     """Bogus args to Session methods produce actionable exceptions."""
 
index 2aadf26d466fe59723eb88901cee8540b9eafec3..b306dcbba2fd4c0075aa525ebf2e9c90c61c6519 100644 (file)
@@ -14,7 +14,7 @@ import sqlalchemy as sa
 class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
     run_inserts = 'once'
     run_deletes = None
-    
+
     @testing.resolve_artifact_names
     def test_basic(self):
         mapper(User, users, properties={
@@ -23,18 +23,18 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                             order_by=Address.id)
         })
         sess = create_session()
-        
+
         q = sess.query(User).options(subqueryload(User.addresses))
-        
+
         def go():
             eq_(
                     [User(id=7, addresses=[
                             Address(id=1, email_address='jack@bean.com')])],
                     q.filter(User.id==7).all()
             )
-        
+
         self.assert_sql_count(testing.db, go, 2)
-        
+
         def go(): 
             eq_(
                 self.static.user_address_result, 
@@ -54,9 +54,9 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                             order_by=Address.id)
         })
         sess = create_session()
-        
+
         u = aliased(User)
-        
+
         q = sess.query(u).options(subqueryload(u.addresses))
 
         def go():
@@ -74,10 +74,10 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                 q.order_by(u.id).all()
             )
         self.assert_sql_count(testing.db, go, 2)
-        
+
         q = sess.query(u).\
                         options(subqueryload_all(u.addresses, Address.dingalings))
-        
+
         def go():
             eq_(
                 [
@@ -93,8 +93,8 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                 q.filter(u.id.in_([8, 9])).all()
             )
         self.assert_sql_count(testing.db, go, 3)
-            
-    
+
+
     @testing.resolve_artifact_names
     def test_from_get(self):
         mapper(User, users, properties={
@@ -103,7 +103,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                             order_by=Address.id)
         })
         sess = create_session()
-        
+
         q = sess.query(User).options(subqueryload(User.addresses))
         def go():
             eq_(
@@ -111,7 +111,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                             Address(id=1, email_address='jack@bean.com')]),
                     q.get(7)
             )
-        
+
         self.assert_sql_count(testing.db, go, 2)
 
     @testing.resolve_artifact_names
@@ -132,7 +132,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             )
 
         self.assert_sql_count(testing.db, go, 2)
-        
+
     @testing.resolve_artifact_names
     def test_disable_dynamic(self):
         """test no subquery option on a dynamic."""
@@ -142,7 +142,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
         })
         mapper(Address, addresses)
         sess = create_session()
-        
+
         # previously this would not raise, but would emit
         # the query needlessly and put the result nowhere.
         assert_raises_message(
@@ -150,7 +150,7 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
             "User.addresses' does not support object population - eager loading cannot be applied.",
             sess.query(User).options(subqueryload(User.addresses)).first,
         )
-        
+
     @testing.resolve_artifact_names
     def test_many_to_many(self):
         mapper(Keyword, keywords)
@@ -290,10 +290,10 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
 
     def test_options_pathing(self):
         self._do_options_test(self._pathing_runs)
-    
+
     def test_mapper_pathing(self):
         self._do_mapper_test(self._pathing_runs)
-    
+
     @testing.resolve_artifact_names
     def _do_options_test(self, configs):
         mapper(User, users, properties={
@@ -309,12 +309,12 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                                         order_by=keywords.c.id) #m2m
         })
         mapper(Keyword, keywords)
-        
+
         callables = {
                         'joinedload':joinedload, 
                     'subqueryload':subqueryload
                 }
-        
+
         for o, i, k, count in configs:
             options = []
             if o in callables:
@@ -349,12 +349,12 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                                             order_by=keywords.c.id)
             })
             mapper(Keyword, keywords)
-            
+
             try:
                 self._do_query_tests([], count)
             finally:
                 clear_mappers()
-    
+
     @testing.resolve_artifact_names
     def _do_query_tests(self, opts, count):
         sess = create_session()
@@ -378,8 +378,8 @@ class EagerTest(_fixtures.FixtureTest, testing.AssertsCompiledSQL):
                     order_by(User.id).all(),
             self.static.user_item_keyword_result[0:1]
         )
-        
-    
+
+
     @testing.resolve_artifact_names
     def test_cyclical(self):
         """A circular eager relationship breaks the cycle with a lazy loader"""
@@ -710,7 +710,7 @@ class SelfReferentialTest(_base.MappedTest):
         n2.append(Node(data='n21'))
         n2.children[0].append(Node(data='n211'))
         n2.children[0].append(Node(data='n212'))
-        
+
         sess.add(n1)
         sess.add(n2)
         sess.flush()
@@ -890,4 +890,4 @@ class SelfReferentialTest(_base.MappedTest):
             ], d)
         self.assert_sql_count(testing.db, go, 4)
 
-    
+
index 9cb9604a7fdc6352832a4d7554f49a3b6c489156..d27bf1af29635e44a305763572ca1ca716297dca 100644 (file)
@@ -23,10 +23,10 @@ class TransactionTest(FixtureTest):
             })
         mapper(Address, addresses)
 
-    
+
 class FixtureDataTest(TransactionTest):
     run_inserts = 'each'
-    
+
     def test_attrs_on_rollback(self):
         sess = self.session()
         u1 = sess.query(User).get(7)
@@ -93,13 +93,13 @@ class AutoExpireTest(TransactionTest):
         s.rollback()
         assert u1 in s
         assert u1 not in s.deleted
-    
+
     def test_gced_delete_on_rollback(self):
         s = self.session()
         u1 = User(name='ed')
         s.add(u1)
         s.commit()
-        
+
         s.delete(u1)
         u1_state = attributes.instance_state(u1)
         assert u1_state in s.identity_map.all_states()
@@ -110,7 +110,7 @@ class AutoExpireTest(TransactionTest):
         del u1
         gc_collect()
         assert u1_state.obj() is None
-        
+
         s.rollback()
         assert u1_state in s.identity_map.all_states()
         u1 = s.query(User).filter_by(name='ed').one()
@@ -120,7 +120,7 @@ class AutoExpireTest(TransactionTest):
         s.flush()
         assert s.scalar(users.count()) == 0
         s.commit()
-        
+
     def test_trans_deleted_cleared_on_rollback(self):
         s = self.session()
         u1 = User(name='ed')
@@ -189,14 +189,14 @@ class TwoPhaseTest(TransactionTest):
     @testing.requires.two_phase_transactions
     def test_rollback_on_prepare(self):
         s = self.session(twophase=True)
-    
+
         u = User(name='ed')
         s.add(u)
         s.prepare()
         s.rollback()
-        
+
         assert u not in s
-        
+
 class RollbackRecoverTest(TransactionTest):
 
     def test_pk_violation(self):
@@ -416,7 +416,7 @@ class AccountingFlagsTest(TransactionTest):
         sess.commit()
 
         testing.db.execute(users.update(users.c.name=='ed').values(name='edward'))
-        
+
         assert u1.name == 'ed'
         sess.expire_all()
         assert u1.name == 'edward'
@@ -429,7 +429,7 @@ class AccountingFlagsTest(TransactionTest):
 
         u1.name = 'edwardo'
         sess.rollback()
-        
+
         testing.db.execute(users.update(users.c.name=='ed').values(name='edward'))
 
         assert u1.name == 'edwardo'
@@ -449,30 +449,30 @@ class AccountingFlagsTest(TransactionTest):
 
         assert u1.name == 'edwardo'
         sess.commit()
-        
+
         assert testing.db.execute(select([users.c.name])).fetchall() == [('edwardo',)]
         assert u1.name == 'edwardo'
 
         sess.delete(u1)
         sess.commit()
-        
+
     def test_preflush_no_accounting(self):
         sess = sessionmaker(_enable_transaction_accounting=False, autocommit=True)()
         u1 = User(name='ed')
         sess.add(u1)
         sess.flush()
-        
+
         sess.begin()
         u1.name = 'edwardo'
         u2 = User(name="some other user")
         sess.add(u2)
-        
+
         sess.rollback()
 
         sess.begin()
         assert testing.db.execute(select([users.c.name])).fetchall() == [('ed',)]
-        
-    
+
+
 class AutoCommitTest(TransactionTest):
     def test_begin_nested_requires_trans(self):
         sess = create_session(autocommit=True)
@@ -483,7 +483,7 @@ class AutoCommitTest(TransactionTest):
 
         u1 = User(name='ed')
         sess.add(u1)
-        
+
         sess.begin()
         u2 = User(name='some other user')
         sess.add(u2)
@@ -533,7 +533,7 @@ class NaturalPKRollbackTest(_base.MappedTest):
 
         session.rollback()
 
-        
-        
+
+
 
 
index e85166f68a8f8563655c9421436c9abb4cad8ea2..d5cd4691620a1ac0f16768434a6136f521f013ad 100644 (file)
@@ -64,7 +64,7 @@ class UnicodeTest(_base.MappedTest):
             uni_type = VARCHAR(50, collation='utf8_unicode_ci')
         else:
             uni_type = sa.Unicode(50)
-        
+
         Table('uni_t1', metadata,
             Column('id',  Integer, primary_key=True,
                    test_needs_autoincrement=True),
@@ -94,7 +94,7 @@ class UnicodeTest(_base.MappedTest):
         session.commit()
 
         self.assert_(t1.txt == txt)
-    
+
     @testing.resolve_artifact_names
     def test_relationship(self):
         mapper(Test, uni_t1, properties={
@@ -226,17 +226,17 @@ class BinaryHistTest(_base.MappedTest, testing.AssertsExecutionResults):
 
     @testing.resolve_artifact_names
     def test_binary_equality(self):
-        
+
         # Py3K
         #data = b"this is some data"
         # Py2K
         data = "this is some data"
         # end Py2K
-        
+
         mapper(Foo, t1)
-        
+
         s = create_session()
-        
+
         f1 = Foo(data=data)
         s.add(f1)
         s.flush()
@@ -251,8 +251,8 @@ class BinaryHistTest(_base.MappedTest, testing.AssertsExecutionResults):
         def go():
             s.flush()
         self.assert_sql_count(testing.db, go, 0)
-        
-        
+
+
 
 
 
@@ -491,12 +491,12 @@ class PassiveDeletesTest(_base.MappedTest):
 
         assert mytable.count().scalar() == 0
         assert myothertable.count().scalar() == 0
-    
+
     @testing.emits_warning(r".*'passive_deletes' is normally configured on one-to-many")
     @testing.resolve_artifact_names
     def test_backwards_pd(self):
         """Test that passive_deletes=True disables a delete from an m2o.
-        
+
         This is not the usual usage and it now raises a warning, but test
         that it works nonetheless.
 
@@ -505,7 +505,7 @@ class PassiveDeletesTest(_base.MappedTest):
             'myclass':relationship(MyClass, cascade="all, delete", passive_deletes=True)
         })
         mapper(MyClass, mytable)
-        
+
         session = create_session()
         mc = MyClass()
         mco = MyOtherClass()
@@ -515,15 +515,15 @@ class PassiveDeletesTest(_base.MappedTest):
 
         assert mytable.count().scalar() == 1
         assert myothertable.count().scalar() == 1
-        
+
         session.expire(mco, ['myclass'])
         session.delete(mco)
         session.flush()
-        
+
         # mytable wasn't deleted, is the point.
         assert mytable.count().scalar() == 1
         assert myothertable.count().scalar() == 0
-    
+
     @testing.resolve_artifact_names
     def test_aaa_m2o_emits_warning(self):
         mapper(MyOtherClass, myothertable, properties={
@@ -531,7 +531,7 @@ class PassiveDeletesTest(_base.MappedTest):
         })
         mapper(MyClass, mytable)
         assert_raises(sa.exc.SAWarning, sa.orm.configure_mappers)
-        
+
 class ExtraPassiveDeletesTest(_base.MappedTest):
     __requires__ = ('foreign_keys',)
 
@@ -628,19 +628,19 @@ class ColumnCollisionTest(_base.MappedTest):
             Column('book_id', String(50)),
             Column('title', String(50))
         )
-    
+
     @testing.resolve_artifact_names
     def test_naming(self):
         class Book(_base.ComparableEntity):
             pass
-    
+
         mapper(Book, book)
         sess = create_session()
-        
+
         b1 = Book(book_id='abc', title='def')
         sess.add(b1)
         sess.flush()
-        
+
         b1.title = 'ghi'
         sess.flush()
         sess.close()
@@ -648,9 +648,9 @@ class ColumnCollisionTest(_base.MappedTest):
             sess.query(Book).first(),
             Book(book_id='abc', title='ghi')
         )
-        
-        
-        
+
+
+
 class DefaultTest(_base.MappedTest):
     """Exercise mappings on columns with DefaultGenerators.
 
@@ -847,12 +847,12 @@ class ColumnPropertyTest(_base.MappedTest):
             Column('id', Integer, ForeignKey('data.id'), primary_key=True),
             Column('c', String(50)),
             )
-            
+
     @classmethod
     def setup_mappers(cls):
         class Data(_base.BasicEntity):
             pass
-        
+
     @testing.resolve_artifact_names
     def test_refreshes(self):
         mapper(Data, data, properties={
@@ -865,7 +865,7 @@ class ColumnPropertyTest(_base.MappedTest):
         m = mapper(Data, data)
         m.add_property('aplusb', column_property(data.c.a + literal_column("' '") + data.c.b))
         self._test()
-    
+
     @testing.resolve_artifact_names
     def test_with_inheritance(self):
         class SubData(Data):
@@ -874,32 +874,32 @@ class ColumnPropertyTest(_base.MappedTest):
             'aplusb':column_property(data.c.a + literal_column("' '") + data.c.b)
         })
         mapper(SubData, subdata, inherits=Data)
-        
+
         sess = create_session()
         sd1 = SubData(a="hello", b="there", c="hi")
         sess.add(sd1)
         sess.flush()
         eq_(sd1.aplusb, "hello there")
-        
+
     @testing.resolve_artifact_names
     def _test(self):
         sess = create_session()
-        
+
         d1 = Data(a="hello", b="there")
         sess.add(d1)
         sess.flush()
-        
+
         eq_(d1.aplusb, "hello there")
-        
+
         d1.b = "bye"
         sess.flush()
         eq_(d1.aplusb, "hello bye")
-        
+
         d1.b = 'foobar'
         d1.aplusb = 'im setting this explicitly'
         sess.flush()
         eq_(d1.aplusb, "im setting this explicitly")
-    
+
 class OneToManyTest(_fixtures.FixtureTest):
     run_inserts = None
 
@@ -1372,29 +1372,29 @@ class SaveTest(_fixtures.FixtureTest):
                 assert instance is self.current_instance
 
         mapper(User, users, batch=False)
-        
+
         evt = Events()
         event.listen(User, "before_insert", evt.before_insert)
         event.listen(User, "after_insert", evt.after_insert)
-        
+
         u1 = User(name='user1')
         u2 = User(name='user2')
 
         session = create_session()
         session.add_all((u1, u2))
         session.flush()
-        
+
         u3 = User(name='user3')
         u4 = User(name='user4')
         u5 = User(name='user5')
-        
+
         session.add_all([u4, u5, u3])
         session.flush()
-        
+
         # test insert ordering is maintained
         assert names == ['user1', 'user2', 'user4', 'user5', 'user3']
         session.expunge_all()
-        
+
         sa.orm.clear_mappers()
 
         m = mapper(User, users)
@@ -1930,14 +1930,14 @@ class BooleanColTest(_base.MappedTest):
 
 class DontAllowFlushOnLoadingObjectTest(_base.MappedTest):
     """Test that objects with NULL identity keys aren't permitted to complete a flush.
-    
+
     User-defined callables that execute during a load may modify state
     on instances which results in their being autoflushed, before attributes
     are populated.  If the primary key identifiers are missing, an explicit assertion
     is needed to check that the object doesn't go through the flush process with
     no net changes and gets placed in the identity map with an incorrect 
     identity key.
-    
+
     """
     @classmethod
     def define_tables(cls, metadata):
@@ -1945,7 +1945,7 @@ class DontAllowFlushOnLoadingObjectTest(_base.MappedTest):
             Column('id', Integer, primary_key=True),
             Column('data', String(30)),
         )
-    
+
     @testing.resolve_artifact_names
     def test_flush_raises(self):
         class T1(_base.ComparableEntity):
@@ -1956,28 +1956,28 @@ class DontAllowFlushOnLoadingObjectTest(_base.MappedTest):
                 # before 'id' was even populated, i.e. a callable
                 # within an attribute_mapped_collection
                 self.__dict__.pop('id', None)
-                
+
                 # generate a change event, perhaps this occurs because
                 # someone wrote a broken attribute_mapped_collection that 
                 # inappropriately fires off change events when it should not,
                 # now we're dirty
                 self.data = 'foo bar'
-                
+
                 # blow away that change, so an UPDATE does not occur
                 # (since it would break)
                 self.__dict__.pop('data', None)
-                
+
                 # flush ! any lazyloader here would trigger
                 # autoflush, for example.
                 sess.flush()
-                
+
         mapper(T1, t1)
-        
+
         sess = Session()
         sess.add(T1(data='test', id=5))
         sess.commit()
         sess.close()
-        
+
         # make sure that invalid state doesn't get into the session
         # with the wrong key.  If the identity key is not NULL, at least
         # the population process would continue after the erroneous flush
@@ -1987,9 +1987,9 @@ class DontAllowFlushOnLoadingObjectTest(_base.MappedTest):
                               'flush is occuring at an inappropriate '
                               'time, such as during a load operation.',
                               sess.query(T1).first)
-        
-        
-    
+
+
+
 class RowSwitchTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -2096,7 +2096,7 @@ class RowSwitchTest(_base.MappedTest):
         assert o5 in sess.deleted
         assert o5.t7s[0] in sess.deleted
         assert o5.t7s[1] in sess.deleted
-        
+
         sess.add(o6)
         sess.flush()
 
@@ -2151,17 +2151,17 @@ class InheritingRowSwitchTest(_base.MappedTest):
 
         class C(P):
             pass
-    
+
     @testing.resolve_artifact_names
     def test_row_switch_no_child_table(self):
         mapper(P, parent)
         mapper(C, child, inherits=P)
-        
+
         sess = create_session()
         c1 = C(id=1, pdata='c1', cdata='c1')
         sess.add(c1)
         sess.flush()
-        
+
         # establish a row switch between c1 and c2.
         # c2 has no value for the "child" table
         c2 = C(id=1, pdata='c2')
@@ -2172,7 +2172,7 @@ class InheritingRowSwitchTest(_base.MappedTest):
             CompiledSQL("UPDATE parent SET pdata=:pdata WHERE parent.id = :parent_id",
                 {'pdata':'c2', 'parent_id':1}
             ),
-            
+
             # this fires as of [ticket:1362], since we synchronzize
             # PK/FKs on UPDATES.  c2 is new so the history shows up as
             # pure added, update occurs.  If a future change limits the
@@ -2181,8 +2181,8 @@ class InheritingRowSwitchTest(_base.MappedTest):
                 {'pid':1, 'child_id':1}
             )
         )
-        
-        
+
+
 
 class TransactionTest(_base.MappedTest):
     __requires__ = ('deferrable_constraints',)
index 10049175a547f04b3e1781aab130e90ec5abd87d..7018f23381ae8887b0bb740f984ef5df40d0c847 100644 (file)
@@ -25,7 +25,7 @@ class AssertsUOW(object):
         for d in deleted:
             uow.register_object(d, isdelete=True)
         return uow
-        
+
     def _assert_uow_size(self,
         session, 
         expected
@@ -51,7 +51,7 @@ class RudimentaryFlushTest(UOWTest):
         a1, a2 = Address(email_address='a1'), Address(email_address='a2')
         u1 = User(name='u1', addresses=[a1, a2])
         sess.add(u1)
-    
+
         self.assert_sql_execution(
                 testing.db,
                 sess.flush,
@@ -81,7 +81,7 @@ class RudimentaryFlushTest(UOWTest):
         u1 = User(name='u1', addresses=[a1, a2])
         sess.add(u1)
         sess.flush()
-        
+
         sess.delete(u1)
         sess.delete(a1)
         sess.delete(a2)
@@ -128,9 +128,9 @@ class RudimentaryFlushTest(UOWTest):
                     {'id':u1.id}
                 ),
         )
-        
+
     def test_many_to_one_save(self):
-        
+
         mapper(User, users)
         mapper(Address, addresses, properties={
             'user':relationship(User)
@@ -141,7 +141,7 @@ class RudimentaryFlushTest(UOWTest):
         a1, a2 = Address(email_address='a1', user=u1), \
                     Address(email_address='a2', user=u1)
         sess.add_all([a1, a2])
-    
+
         self.assert_sql_execution(
                 testing.db,
                 sess.flush,
@@ -173,7 +173,7 @@ class RudimentaryFlushTest(UOWTest):
                     Address(email_address='a2', user=u1)
         sess.add_all([a1, a2])
         sess.flush()
-        
+
         sess.delete(u1)
         sess.delete(a1)
         sess.delete(a2)
@@ -233,25 +233,25 @@ class RudimentaryFlushTest(UOWTest):
         parent = User(name='p1')
         c1, c2 = Address(email_address='c1', parent=parent), \
                     Address(email_address='c2', parent=parent)
-        
+
         session = Session()
         session.add_all([c1, c2])
         session.add(parent)
 
         session.flush()
-       
+
         pid = parent.id
         c1id = c1.id
         c2id = c2.id
-        
+
         session.expire(parent)
         session.expire(c1)
         session.expire(c2)
-        
+
         session.delete(c1)
         session.delete(c2)
         session.delete(parent)
-        
+
         # testing that relationships 
         # are loaded even if all ids/references are 
         # expired
@@ -291,13 +291,13 @@ class RudimentaryFlushTest(UOWTest):
                 lambda ctx: {'id': pid}
             ),
         )
-    
+
     def test_many_to_many(self):
         mapper(Item, items, properties={
             'keywords':relationship(Keyword, secondary=item_keywords)
         })
         mapper(Keyword, keywords)
-        
+
         sess = create_session()
         k1 = Keyword(name='k1')
         i1 = Item(description='i1', keywords=[k1])
@@ -321,7 +321,7 @@ class RudimentaryFlushTest(UOWTest):
                     lambda ctx:{'item_id':i1.id, 'keyword_id':k1.id}
                 )
         )
-        
+
         # test that keywords collection isn't loaded
         sess.expire(i1, ['keywords'])
         i1.description = 'i2'
@@ -332,7 +332,7 @@ class RudimentaryFlushTest(UOWTest):
                             "WHERE items.id = :items_id", 
                             lambda ctx:{'description':'i2', 'items_id':i1.id})
         )
-        
+
     def test_m2o_flush_size(self):
         mapper(User, users)
         mapper(Address, addresses, properties={
@@ -389,13 +389,13 @@ class SingleCycleTest(UOWTest):
 
         n2, n3 = Node(data='n2'), Node(data='n3')
         n1 = Node(data='n1', children=[n2, n3])
-        
+
         sess.add(n1)
-    
+
         self.assert_sql_execution(
                 testing.db,
                 sess.flush,
-                
+
                 CompiledSQL(
                     "INSERT INTO nodes (parent_id, data) VALUES "
                     "(:parent_id, :data)",
@@ -426,7 +426,7 @@ class SingleCycleTest(UOWTest):
 
         sess.add(n1)
         sess.flush()
-        
+
         sess.delete(n1)
         sess.delete(n2)
         sess.delete(n3)
@@ -466,7 +466,7 @@ class SingleCycleTest(UOWTest):
                 CompiledSQL("DELETE FROM nodes WHERE nodes.id = :id", 
                     lambda ctx:{'id':n1.id})
         )
-    
+
     def test_many_to_one_save(self):
         mapper(Node, nodes, properties={
             'parent':relationship(Node, remote_side=nodes.c.id)
@@ -512,7 +512,7 @@ class SingleCycleTest(UOWTest):
 
         sess.add_all([n2, n3])
         sess.flush()
-        
+
         sess.delete(n1)
         sess.delete(n2)
         sess.delete(n3)
@@ -524,7 +524,7 @@ class SingleCycleTest(UOWTest):
                 CompiledSQL("DELETE FROM nodes WHERE nodes.id = :id", 
                         lambda ctx: {'id':n1.id})
         )
-    
+
     def test_cycle_rowswitch(self):
         mapper(Node, nodes, properties={
             'children':relationship(Node)
@@ -540,7 +540,7 @@ class SingleCycleTest(UOWTest):
         n3.id = n2.id
         n1.children.append(n3)
         sess.flush()
-        
+
     def test_bidirectional_mutations_one(self):
         mapper(Node, nodes, properties={
             'children':relationship(Node, 
@@ -556,11 +556,11 @@ class SingleCycleTest(UOWTest):
         sess.delete(n2)
         n1.children.append(n3)
         sess.flush()
-        
+
         sess.delete(n1)
         sess.delete(n3)
         sess.flush()
-        
+
     def test_bidirectional_multilevel_save(self):
         mapper(Node, nodes, properties={
             'children':relationship(Node, 
@@ -627,27 +627,27 @@ class SingleCycleTest(UOWTest):
         self._assert_uow_size(sess, 2)
 
         sess.flush()
-    
+
         n1.data='jack'
 
         self._assert_uow_size(sess, 2)
         sess.flush()
-    
+
         n2 = Node(data='foo')
         sess.add(n2)
         sess.flush()
-    
+
         n1.children.append(n2)
 
         self._assert_uow_size(sess, 3)
-    
+
         sess.flush()
-    
+
         sess = create_session()
         n1 = sess.query(Node).first()
         n1.data='ed'
         self._assert_uow_size(sess, 2)
-    
+
         n1.children
         self._assert_uow_size(sess, 2)
 
@@ -658,25 +658,25 @@ class SingleCycleTest(UOWTest):
 
         parent = Node()
         c1, c2 = Node(parent=parent), Node(parent=parent)
-        
+
         session = Session()
         session.add_all([c1, c2])
         session.add(parent)
 
         session.flush()
-       
+
         pid = parent.id
         c1id = c1.id
         c2id = c2.id
-        
+
         session.expire(parent)
         session.expire(c1)
         session.expire(c2)
-        
+
         session.delete(c1)
         session.delete(c2)
         session.delete(parent)
-        
+
         # testing that relationships 
         # are loaded even if all ids/references are 
         # expired
@@ -718,9 +718,9 @@ class SingleCycleTest(UOWTest):
                 lambda ctx: {'id': pid}
             ),
         )
-        
-        
-        
+
+
+
 class SingleCyclePlusAttributeTest(_base.MappedTest,
                     testing.AssertsExecutionResults, AssertsUOW):
     @classmethod
@@ -731,7 +731,7 @@ class SingleCyclePlusAttributeTest(_base.MappedTest,
             Column('parent_id', Integer, ForeignKey('nodes.id')),
             Column('data', String(30))
         )
-        
+
         Table('foobars', metadata,
             Column('id', Integer, primary_key=True,
                                     test_needs_autoincrement=True),
@@ -758,13 +758,13 @@ class SingleCyclePlusAttributeTest(_base.MappedTest,
         sess.add(n1)
         # ensure "foobars" doesn't get yanked in here
         self._assert_uow_size(sess, 3)
-        
+
         n1.foobars.append(FooBar())
         # saveupdateall/deleteall for FooBar added here,
         # plus processstate node.foobars 
         # currently the "all" procs stay in pairs
         self._assert_uow_size(sess, 6)
-        
+
         sess.flush()
 
 class SingleCycleM2MTest(_base.MappedTest, 
@@ -779,19 +779,19 @@ class SingleCycleM2MTest(_base.MappedTest,
             Column('data', String(30)),
             Column('favorite_node_id', Integer, ForeignKey('nodes.id'))
         )
-        
+
         node_to_nodes =Table('node_to_nodes', metadata,
             Column('left_node_id', Integer, 
                             ForeignKey('nodes.id'),primary_key=True),
             Column('right_node_id', Integer, 
                             ForeignKey('nodes.id'),primary_key=True),
             )
-    
+
     @testing.resolve_artifact_names
     def test_many_to_many_one(self):
         class Node(Base):
             pass
-        
+
         mapper(Node, nodes, properties={
             'children':relationship(Node, secondary=node_to_nodes,
                 primaryjoin=nodes.c.id==node_to_nodes.c.left_node_id,
@@ -800,24 +800,24 @@ class SingleCycleM2MTest(_base.MappedTest,
             ),
             'favorite':relationship(Node, remote_side=nodes.c.id)
         })
-        
+
         sess = create_session()
         n1 = Node(data='n1')
         n2 = Node(data='n2')
         n3 = Node(data='n3')
         n4 = Node(data='n4')
         n5 = Node(data='n5')
-        
+
         n4.favorite = n3
         n1.favorite = n5
         n5.favorite = n2
-        
+
         n1.children = [n2, n3, n4]
         n2.children = [n3, n5]
         n3.children = [n5, n4]
-        
+
         sess.add_all([n1, n2, n3, n4, n5])
-        
+
         # can't really assert the SQL on this easily
         # since there's too many ways to insert the rows.
         # so check the end result
@@ -834,9 +834,9 @@ class SingleCycleM2MTest(_base.MappedTest,
                     (n3.id, n5.id), (n3.id, n4.id)
                 ])
         )
-        
+
         sess.delete(n1)
-        
+
         self.assert_sql_execution(
                 testing.db,
                 sess.flush,
@@ -849,7 +849,7 @@ class SingleCycleM2MTest(_base.MappedTest,
                     "node_to_nodes.right_node_id AND nodes.id = "
                     "node_to_nodes.left_node_id" ,
                     lambda ctx:{u'param_1': n1.id},
-                ),    
+                ),
                 CompiledSQL(
                     "DELETE FROM node_to_nodes WHERE "
                     "node_to_nodes.left_node_id = :left_node_id AND "
@@ -865,15 +865,15 @@ class SingleCycleM2MTest(_base.MappedTest,
                     lambda ctx:{'id': n1.id}
                 ),
         )
-        
+
         for n in [n2, n3, n4, n5]:
             sess.delete(n)
-        
+
         # load these collections
         # outside of the flush() below
         n4.children
         n5.children
-        
+
         self.assert_sql_execution(
             testing.db,
             sess.flush,
@@ -897,7 +897,7 @@ class SingleCycleM2MTest(_base.MappedTest,
                 lambda ctx:[{'id': n2.id}, {'id': n3.id}]
             ),
         )
-    
+
 class RowswitchAccountingTest(_base.MappedTest):
     @classmethod
     def define_tables(cls, metadata):
@@ -907,7 +907,7 @@ class RowswitchAccountingTest(_base.MappedTest):
         Table('child', metadata, 
             Column('id', Integer, ForeignKey('parent.id'), primary_key=True)
         )
-    
+
     @testing.resolve_artifact_names
     def test_accounting_for_rowswitch(self):
         class Parent(object):
@@ -923,7 +923,7 @@ class RowswitchAccountingTest(_base.MappedTest):
                                     backref="parent")
         })
         mapper(Child, child)
-        
+
         sess = create_session(autocommit=False)
 
         p1 = Parent(1)
@@ -964,7 +964,7 @@ class BatchInsertsTest(_base.MappedTest, testing.AssertsExecutionResults):
     def test_batch_interaction(self):
         """test batching groups same-structured, primary 
         key present statements together.
-        
+
         """
         class T(Base):
             pass
index e196a961729c8773993ec232bee0836a04218ed8..362b54cf092408f0b745696c5eb1d4c8a9d29c69 100644 (file)
@@ -215,5 +215,5 @@ class IdentityKeyTest(_fixtures.FixtureTest):
         row = {users.c.id: 1, users.c.name: "Frank"}
         key = util.identity_key(User, row=row)
         eq_(key, (User, (1,)))
-    
+
 
index 94c0efc10fb3874d90a0a5ca87201f784ac3255e..9da97dc1e92163362ce827c65c051453b54d2905 100644 (file)
@@ -26,13 +26,13 @@ _uuids = [
     '782a5f04b4364a53a6fce762f48921c1',
     'bef510f2420f4476a7629013ead237f5',
     ]
-    
+
 def make_uuid():
     """generate uuids even on Python 2.4 which has no 'uuid'"""
     return _uuids.pop(0)
 
 class VersioningTest(_base.MappedTest):
-    
+
     @classmethod
     def define_tables(cls, metadata):
         Table('version_table', metadata,
@@ -131,11 +131,11 @@ class VersioningTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_bump_version(self):
         """test that version number can be bumped.
-        
+
         Ensures that the UPDATE or DELETE is against the 
         last committed version of version_id_col, not the modified 
         state.
-        
+
         """
         mapper(Foo, version_table, 
                 version_id_col=version_table.c.version_id)
@@ -148,19 +148,19 @@ class VersioningTest(_base.MappedTest):
         f1.version_id = 2
         s1.commit()
         eq_(f1.version_id, 2)
-        
+
         # skip an id, test that history
         # is honored
         f1.version_id = 4
         f1.value = "something new"
         s1.commit()
         eq_(f1.version_id, 4)
-        
+
         f1.version_id = 5
         s1.delete(f1)
         s1.commit()
         eq_(s1.query(Foo).count(), 0)
-        
+
     @testing.emits_warning(r'.*does not support updated rowcount')
     @engines.close_open_connections
     @testing.resolve_artifact_names
@@ -189,7 +189,7 @@ class VersioningTest(_base.MappedTest):
 
         # reload it - this expires the old version first
         s1.refresh(f1s1, lockmode='read')
-        
+
         # now assert version OK
         s1.query(Foo).with_lockmode('read').get(f1s1.id)
 
@@ -216,13 +216,13 @@ class VersioningTest(_base.MappedTest):
         f1s2 = s2.query(Foo).get(f1s1.id)
         s2.refresh(f1s2, lockmode='update')
         f1s2.value='f1 new value'
-        
+
         assert_raises(
             exc.DBAPIError,
             s1.refresh, f1s1, lockmode='update_nowait'
         )
         s1.rollback()
-        
+
         s2.commit()
         s1.refresh(f1s1, lockmode='update_nowait')
         assert f1s1.version_id == f1s2.version_id
@@ -281,16 +281,16 @@ class RowSwitchTest(_base.MappedTest):
         session.add(P(id='P1', data='P version 1'))
         session.commit()
         session.close()
-        
+
         p = session.query(P).first()
         session.delete(p)
         session.add(P(id='P1', data="really a row-switch"))
         session.commit()
-    
+
     @testing.resolve_artifact_names
     def test_child_row_switch(self):
         assert P.c.property.strategy.use_get
-        
+
         session = sessionmaker()()
         session.add(P(id='P1', data='P version 1'))
         session.commit()
@@ -369,27 +369,27 @@ class AlternateGeneratorTest(_base.MappedTest):
     @testing.resolve_artifact_names
     def test_child_row_switch_two(self):
         Session = sessionmaker()
-        
+
         # TODO: not sure this test is 
         # testing exactly what its looking for
-        
+
         sess1 = Session()
         sess1.add(P(id='P1', data='P version 1'))
         sess1.commit()
         sess1.close()
-        
+
         p1 = sess1.query(P).first()
 
         sess2 = Session()
         p2 = sess2.query(P).first()
-        
+
         sess1.delete(p1)
         sess1.commit()
-        
+
         # this can be removed and it still passes
         sess1.add(P(id='P1', data='P version 2'))
         sess1.commit()
-        
+
         p2.data = 'P overwritten by concurrent tx'
         assert_raises_message(
             orm.exc.StaleDataError,
@@ -397,12 +397,12 @@ class AlternateGeneratorTest(_base.MappedTest):
             r"1 row\(s\); 0 were matched.",
             sess2.commit
         )
-        
+
 
 class InheritanceTwoVersionIdsTest(_base.MappedTest):
     """Test versioning where both parent/child table have a
     versioning column.
-    
+
     """
     @classmethod
     def define_tables(cls, metadata):
@@ -454,7 +454,7 @@ class InheritanceTwoVersionIdsTest(_base.MappedTest):
 
         # base is populated
         eq_(select([base.c.version_id]).scalar(), 1)
-    
+
     @testing.resolve_artifact_names
     def test_sub_only(self):
         mapper(Base, base)
@@ -471,12 +471,12 @@ class InheritanceTwoVersionIdsTest(_base.MappedTest):
 
         # base is not
         eq_(select([base.c.version_id]).scalar(), None)
-        
+
     @testing.resolve_artifact_names
     def test_mismatch_version_col_warning(self):
         mapper(Base, base, 
                 version_id_col=base.c.version_id)
-        
+
         assert_raises_message(
             exc.SAWarning,
             "Inheriting version_id_col 'version_id' does not "
@@ -487,4 +487,3 @@ class InheritanceTwoVersionIdsTest(_base.MappedTest):
             mapper,
             Sub, sub, inherits=Base, 
                 version_id_col=sub.c.version_id)
-        
\ No newline at end of file
index dfb6df2cca9f320a3588bd1cf10c845d8b0c7503..1d03cb5ce417b3fab8ff24bfdc34007e7f58ec3d 100644 (file)
@@ -14,4 +14,4 @@ Current automated stress and performance tests are in test/aaa_profiling/,
 which test either for expected function call count, or flat growth in memory 
 usage over time.   These tests are part of the automated test suite
 and are maintained for 100% success rate along Python versions from 2.4 through
-current 3 versions.   
\ No newline at end of file
+current 3 versions.
\ No newline at end of file
index 126c9c707ceff6a7df19008d667df8c07e00311a..f64c73c690c9366ef41a82c14b9e6df24379df35 100644 (file)
@@ -38,14 +38,14 @@ def setup():
     data = [{'name':'John Doe','sex':1,'age':35, 'type':'employee'}] * 100
     for j in xrange(500):
         i.execute(data)
-        
+
     # note we arent fetching from employee_table,
     # so we can leave it empty even though its "incorrect"
     #i = Employee_table.insert()
     #data = [{'foo':'foo', 'bar':'bar':'bat':'bat'}] * 100
     #for j in xrange(500):
     #    i.execute(data)
-        
+
     print "Inserted 50,000 rows"
 
 def sqlite_select(entity_cls):
index 46703b6da6ef5819b058b4686caf7605ee4ac8b9..d24376cc9c9fd39081ab7646c083b20dddc108fe 100644 (file)
@@ -23,50 +23,50 @@ from sqlalchemy.ext.declarative import declarative_base
 import random
 import os
 from decimal import Decimal
-    
+
 Base = declarative_base()
 
 class Employee(Base):
     __tablename__ = 'employee'
-    
+
     id = Column(Integer, primary_key=True)
     name = Column(String(100), nullable=False)
     type = Column(String(50), nullable=False)
-    
+
     __mapper_args__ = {'polymorphic_on':type}
 
 class Boss(Employee):
     __tablename__ = 'boss'
-    
+
     id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
     golf_average = Column(Numeric)
-    
+
     __mapper_args__ = {'polymorphic_identity':'boss'}
-    
+
 class Grunt(Employee):
     __tablename__ = 'grunt'
-    
+
     id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
     savings = Column(Numeric)
-    
+
     employer_id = Column(Integer, ForeignKey('boss.id'))
 
     # Configure an 'employer' relationship, where Grunt references 
     # Boss.  This is a joined-table subclass to subclass relationship, 
     # which is a less typical case.
-    
+
     # In 0.7, "Boss.id" is the "id" column of "boss", as would be expected.
     if __version__ >= "0.7":
         employer = relationship("Boss", backref="employees", 
                                     primaryjoin=Boss.id==employer_id)
-                                    
-    # Prior to 0.7, "Boss.id" is the "id" column of "employee".  
+
+    # Prior to 0.7, "Boss.id" is the "id" column of "employee".
     # Long story.  So we hardwire the relationship against the "id"
     # column of Boss' table.
     elif __version__ >= "0.6":
         employer = relationship("Boss", backref="employees", 
                                 primaryjoin=Boss.__table__.c.id==employer_id)
-                                
+
     # In 0.5, the many-to-one loader wouldn't recognize the above as a 
     # simple "identity map" fetch.  So to give 0.5 a chance to emit
     # the same amount of SQL as 0.6, we hardwire the relationship against
@@ -75,9 +75,9 @@ class Grunt(Employee):
         employer = relationship("Boss", backref="employees", 
                                 primaryjoin=Employee.__table__.c.id==employer_id, 
                                 foreign_keys=employer_id)
-        
+
     __mapper_args__ = {'polymorphic_identity':'grunt'}
-    
+
 if os.path.exists('orm2010.db'):
     os.remove('orm2010.db')
 # use a file based database so that cursor.execute() has some 
@@ -99,9 +99,9 @@ def runit():
     ]
 
     sess.add_all(bosses)
-    
-    
-    # create 10000 Grunt objects.  
+
+
+    # create 10000 Grunt objects.
     grunts = [
         Grunt(
             name="Grunt %d" % i,
@@ -109,7 +109,7 @@ def runit():
         )
         for i in xrange(10000)
     ]
-    
+
     # Assign each Grunt a Boss.  Look them up in the DB
     # to simulate a little bit of two-way activity with the 
     # DB while we populate.  Autoflush occurs on each query.
@@ -121,15 +121,15 @@ def runit():
                     first()
         for grunt in grunts[0:100]:
             grunt.employer = boss
-        
+
         grunts = grunts[100:]
 
     sess.commit()
 
     report = []
-    
+
     # load all the Grunts, print a report with their name, stats,
-    # and their bosses' stats.  
+    # and their bosses' stats.
     for grunt in sess.query(Grunt):
         # here, the overhead of a many-to-one fetch of 
         # "grunt.employer" directly from the identity map 
@@ -160,7 +160,7 @@ print 'Total executemany calls: %d' \
                          "objects>", 0)
 
 os.system("runsnake %s" % filename)
-    
+
 # SQLA Version: 0.7b1
 # Total calls 4956750
 # Total execute calls: 11201
@@ -178,9 +178,9 @@ os.system("runsnake %s" % filename)
 
 
 
-    
 
 
-    
+
+
 
 
index 2fe4f758fc53acdda1a6abc300e7a98caadd7d95..c1258e73238088beadc693d2a2c2bcbd0d456d7a 100644 (file)
@@ -23,7 +23,7 @@ class SessionTest(TestBase, AssertsExecutionResults):
             Column('c2', String(30)),
             Column('t1id', Integer, ForeignKey('t1.c1'))
             )
-        
+
         metadata.create_all()
 
         l = []
@@ -35,7 +35,7 @@ class SessionTest(TestBase, AssertsExecutionResults):
             for y in range(1, 100):
                 l.append({'c2':'this is t2 #%d' % y, 't1id':x})
             t2.insert().execute(*l)
-        
+
         class T1(_fixtures.Base):
             pass
         class T2(_fixtures.Base):
@@ -45,12 +45,12 @@ class SessionTest(TestBase, AssertsExecutionResults):
             't2s':relationship(T2, backref='t1')
         })
         mapper(T2, t2)
-    
+
     @classmethod
     def teardown_class(cls):
         metadata.drop_all()
         clear_mappers()
-        
+
     @profiling.profiled('clean', report=True)
     def test_session_clean(self):
         for x in range(0, ITERATIONS):
@@ -68,7 +68,7 @@ class SessionTest(TestBase, AssertsExecutionResults):
         for x in range(0, ITERATIONS):
             sess = create_session()
             t1s = sess.query(T1).filter(T1.c1.between(15, 48)).all()
-            
+
             for index in [2, 7, 12, 15, 18, 20]:
                 t1s[index].c2 = 'this is some modified text'
                 for t2 in t1s[index].t2s:
@@ -76,7 +76,7 @@ class SessionTest(TestBase, AssertsExecutionResults):
 
             del t1s
             gc_collect()
-            
+
             sess.close()
             del sess
             gc_collect()
index 7bc3ab31f3c8d83c48de5c2ee5bbc6f5a65110cf..97220d4dd9afa5dc2916f56687653163579303ee 100644 (file)
@@ -94,31 +94,31 @@ class CaseTest(TestBase, AssertsCompiledSQL):
 
     def test_literal_interpretation(self):
         t = table('test', column('col1'))
-        
+
         assert_raises(exc.ArgumentError, case, [("x", "y")])
-        
+
         self.assert_compile(case([("x", "y")], value=t.c.col1), "CASE test.col1 WHEN :param_1 THEN :param_2 END")
         self.assert_compile(case([(t.c.col1==7, "y")], else_="z"), "CASE WHEN (test.col1 = :col1_1) THEN :param_1 ELSE :param_2 END")
-        
+
     def test_text_doesnt_explode(self):
 
         for s in [
             select([case([(info_table.c.info == 'pk_4_data',
                    text("'yes'"))], else_=text("'no'"
                    ))]).order_by(info_table.c.info),
-                   
+
            select([case([(info_table.c.info == 'pk_4_data',
                   literal_column("'yes'"))], else_=literal_column("'no'"
                   ))]).order_by(info_table.c.info),
-                   
+
         ]:
             eq_(s.execute().fetchall(), [
                 (u'no', ), (u'no', ), (u'no', ), (u'yes', ),
                 (u'no', ), (u'no', ),
                 ])
-        
-        
-        
+
+
+
     @testing.fails_on('firebird', 'FIXME: unknown')
     @testing.fails_on('maxdb', 'FIXME: unknown')
     def testcase_with_dict(self):
@@ -146,7 +146,7 @@ class CaseTest(TestBase, AssertsCompiledSQL):
             ],
             whereclause=info_table.c.pk < 4,
             from_obj=[info_table])
-        
+
         assert simple_query.execute().fetchall() == [
             ('one', 1),
             ('two', 2),
index b34eaeaaec0fcd42d67aa53f31c115a7ea63b66f..d63e41e90cf4ec184afab2bdecef1f59d4293077 100644 (file)
@@ -85,15 +85,15 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                             "SELECT mytable.myid, mytable.name, mytable.description, "
                             "myothertable.otherid, myothertable.othername FROM mytable, "
                             "myothertable")
-    
+
     def test_invalid_col_argument(self):
         assert_raises(exc.ArgumentError, select, table1)
         assert_raises(exc.ArgumentError, select, table1.c.myid)
-    
+
     def test_from_subquery(self):
         """tests placing select statements in the column clause of another select, for the
         purposes of selecting from the exported columns of that select."""
-        
+
         s = select([table1], table1.c.name == 'jack')
         self.assert_compile(
             select(
@@ -163,7 +163,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             select([ClauseList(column('a'), column('b'))]).select_from('sometable'), 
             'SELECT a, b FROM sometable'
         )
-        
+
     def test_use_labels(self):
         self.assert_compile(
             select([table1.c.myid==5], use_labels=True),
@@ -184,15 +184,15 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             select([cast("data", Integer)], use_labels=True),
             "SELECT CAST(:param_1 AS INTEGER) AS anon_1"
         )
-        
+
         self.assert_compile(
             select([func.sum(func.lala(table1.c.myid).label('foo')).label('bar')]),
             "SELECT sum(lala(mytable.myid)) AS bar FROM mytable"
         )
-    
+
     def test_paramstyles(self):
         stmt = text("select :foo, :bar, :bat from sometable")
-        
+
         self.assert_compile(
             stmt,
             "select ?, ?, ? from sometable"
@@ -218,10 +218,10 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "select %(foo)s, %(bar)s, %(bat)s from sometable"
             , dialect=default.DefaultDialect(paramstyle='pyformat')
         )
-        
+
     def test_dupe_columns(self):
         """test that deduping is performed against clause element identity, not rendered result."""
-        
+
         self.assert_compile(
             select([column('a'), column('a'), column('a')]),
             "SELECT a, a, a"
@@ -241,7 +241,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "SELECT a, b"
             , dialect=default.DefaultDialect()
         )
-        
+
         self.assert_compile(
             select([bindparam('a'), bindparam('b'), bindparam('c')]),
             "SELECT :a, :b, :c"
@@ -258,11 +258,11 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             select(["a", "a", "a"]),
             "SELECT a, a, a"
         )
-        
+
         s = select([bindparam('a'), bindparam('b'), bindparam('c')])
         s = s.compile(dialect=default.DefaultDialect(paramstyle='qmark'))
         eq_(s.positiontup, ['a', 'b', 'c'])
-        
+
     def test_nested_uselabels(self):
         """test nested anonymous label generation.  this
         essentially tests the ANONYMOUS_LABEL regex.
@@ -285,7 +285,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                             'mytable.name AS name, mytable.description '
                             'AS description FROM mytable) AS anon_2) '
                             'AS anon_1')
-        
+
     def test_dont_overcorrelate(self):
         self.assert_compile(select([table1], from_obj=[table1,
                             table1.select()]),
@@ -294,7 +294,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                             "mytable.myid AS myid, mytable.name AS "
                             "name, mytable.description AS description "
                             "FROM mytable)")
-    
+
     def test_full_correlate(self):
         # intentional
         t = table('t', column('a'), column('b'))
@@ -302,7 +302,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
 
         s2 = select([t.c.a, s])
         self.assert_compile(s2, """SELECT t.a, (SELECT t.a WHERE t.a = :a_1) AS anon_1 FROM t""")
-    
+
         # unintentional
         t2 = table('t2', column('c'), column('d'))
         s = select([t.c.a]).where(t.c.a==t2.c.d).as_scalar()
@@ -313,18 +313,18 @@ class SelectTest(TestBase, AssertsCompiledSQL):
         s = s.correlate(t, t2)
         s2 =select([t, t2, s])
         self.assert_compile(s, "SELECT t.a WHERE t.a = t2.d")
-        
+
     def test_exists(self):
         s = select([table1.c.myid]).where(table1.c.myid==5)
-        
+
         self.assert_compile(exists(s), 
                     "EXISTS (SELECT mytable.myid FROM mytable WHERE mytable.myid = :myid_1)"
                 )
-        
+
         self.assert_compile(exists(s.as_scalar()), 
                     "EXISTS (SELECT mytable.myid FROM mytable WHERE mytable.myid = :myid_1)"
                 )
-        
+
         self.assert_compile(exists([table1.c.myid], table1.c.myid
                             == 5).select(),
                             'SELECT EXISTS (SELECT mytable.myid FROM '
@@ -375,7 +375,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                             'WHERE EXISTS (SELECT * FROM myothertable '
                             'AS myothertable_1 WHERE '
                             'myothertable_1.otherid = mytable.myid)')
-        
+
         self.assert_compile(
             select([
                 or_(
@@ -388,7 +388,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "OR (EXISTS (SELECT * FROM myothertable WHERE "
             "myothertable.otherid = :otherid_2)) AS anon_1"
         )
-        
+
 
     def test_where_subquery(self):
         s = select([addresses.c.street], addresses.c.user_id
@@ -619,7 +619,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(
                 label('bar', column('foo', type_=String))+ 'foo', 
                 'foo || :param_1')
-    
+
 
     def test_conjunctions(self):
         a, b, c = 'a', 'b', 'c'
@@ -630,7 +630,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             select([x.label('foo')]),
             'SELECT a AND b AND c AS foo'
         )
-    
+
         self.assert_compile(
             and_(table1.c.myid == 12, table1.c.name=='asdf', 
                 table2.c.othername == 'foo', "sysdate() = today()"),
@@ -651,7 +651,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
              'today()', 
             checkparams = {'othername_1': 'asdf', 'othername_2':'foo', 'otherid_1': 9, 'myid_1': 12}
         )
-        
+
 
     def test_distinct(self):
         self.assert_compile(
@@ -678,7 +678,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             select([func.count(distinct(table1.c.myid))]), 
             "SELECT count(DISTINCT mytable.myid) AS count_1 FROM mytable"
         )
-    
+
     def test_operators(self):
         for (py_op, sql_op) in ((operator.add, '+'), (operator.mul, '*'),
                                 (operator.sub, '-'), 
@@ -730,7 +730,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                 self.assert_(compiled == fwd_sql or compiled == rev_sql,
                              "\n'" + compiled + "'\n does not match\n'" +
                              fwd_sql + "'\n or\n'" + rev_sql + "'")
-        
+
         for (py_op, op) in (
             (operator.neg, '-'),
             (operator.inv, 'NOT '),
@@ -739,11 +739,11 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                 (table1.c.myid, "mytable.myid"),
                 (literal("foo"), ":param_1"),
             ):
-            
+
                 compiled = str(py_op(expr))
                 sql = "%s%s" % (op, sql)
                 eq_(compiled, sql)
-        
+
         self.assert_compile(
          table1.select((table1.c.myid != 12) & ~(table1.c.name=='john')),
          "SELECT mytable.myid, mytable.name, mytable.description FROM "
@@ -837,7 +837,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                 postgresql.PGDialect()),
         ]:
             self.assert_compile(expr, check, dialect=dialect)
-    
+
     def test_match(self):
         for expr, check, dialect in [
             (table1.c.myid.match('somstr'), 
@@ -853,7 +853,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                         postgresql.dialect()),
             (table1.c.myid.match('somstr'), 
                         "CONTAINS (mytable.myid, :myid_1)", 
-                        oracle.dialect()),            
+                        oracle.dialect()),
         ]:
             self.assert_compile(expr, check, dialect=dialect)
 
@@ -1160,7 +1160,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "SELECT column1 AS foobar, column2 AS hoho, myid FROM "
             "(SELECT column1 AS foobar, column2 AS hoho, mytable.myid AS myid FROM mytable)"
         )
-        
+
         self.assert_compile(
             select(['col1','col2'], from_obj='tablename').alias('myalias'),
             "SELECT col1, col2 FROM tablename"
@@ -1189,7 +1189,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                 checkparams={'bar':4, 'whee': 7},
                 dialect=dialect
         )
-        
+
         # test escaping out text() params with a backslash
         self.assert_compile(
             text("select * from foo where clock='05:06:07' and mork='\:mindy'"),
@@ -1243,23 +1243,23 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                     "SELECT CURRENT_DATE + s.a AS dates FROM generate_series(:x, :y, :z) as s(a)", 
                     checkparams={'y': None, 'x': None, 'z': None}
                 )
-        
+
         self.assert_compile(
                     s.params(x=5, y=6, z=7), 
                     "SELECT CURRENT_DATE + s.a AS dates FROM generate_series(:x, :y, :z) as s(a)", 
                     checkparams={'y': 6, 'x': 5, 'z': 7}
                 )
-        
+
     @testing.emits_warning('.*empty sequence.*')
     def test_render_binds_as_literal(self):
         """test a compiler that renders binds inline into 
         SQL in the columns clause."""
-        
+
         dialect = default.DefaultDialect()
         class Compiler(dialect.statement_compiler):
             ansi_bind_rules = True
         dialect.statement_compiler = Compiler
-        
+
         self.assert_compile(
             select([literal("someliteral")]),
             "SELECT 'someliteral'",
@@ -1283,23 +1283,23 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "SELECT mod(mytable.myid, 5) AS mod_1 FROM mytable",
             dialect=dialect
         )
-        
+
         self.assert_compile(
             select([literal("foo").in_([])]),
             "SELECT 'foo' != 'foo' AS anon_1",
             dialect=dialect
         )
-        
+
         assert_raises(
             exc.CompileError,
             bindparam("foo").in_([]).compile, dialect=dialect
         )
-        
-        
+
+
     def test_literal(self):
-        
+
         self.assert_compile(select([literal('foo')]), "SELECT :param_1")
-        
+
         self.assert_compile(select([literal("foo") + literal("bar")], from_obj=[table1]),
             "SELECT :param_1 || :param_2 AS anon_1 FROM mytable")
 
@@ -1334,7 +1334,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                 expr, "SELECT mytable.name COLLATE latin1_german2_ci AS anon_1 FROM mytable")
 
         assert table1.c.name.collate('latin1_german2_ci').type is table1.c.name.type
-        
+
         expr = select([table1.c.name.collate('latin1_german2_ci').label('k1')]).order_by('k1')
         self.assert_compile(expr,"SELECT mytable.name COLLATE latin1_german2_ci AS k1 FROM mytable ORDER BY k1")
 
@@ -1384,8 +1384,8 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             '''"table%name"."spaces % more spaces" AS "table%name_spaces % '''\
             '''more spaces" FROM "table%name"'''
         )
-        
-        
+
+
     def test_joins(self):
         self.assert_compile(
             join(table2, table1, table1.c.myid == table2.c.otherid).select(),
@@ -1473,7 +1473,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "select #1 has 2 columns, select #2 has 3",
             union, table3.select(), table1.select()
         )
-    
+
         x = union(
               select([table1], table1.c.myid == 5),
               select([table1], table1.c.myid == 12),
@@ -1494,7 +1494,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                                 "FROM mytable UNION SELECT mytable.myid, mytable.name, " 
                                 "mytable.description FROM mytable) UNION SELECT mytable.myid,"
                                 " mytable.name, mytable.description FROM mytable")
-        
+
         u1 = union(
             select([table1.c.myid, table1.c.name]),
             select([table2]),
@@ -1507,7 +1507,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                                 "FROM thirdtable")
 
         assert u1.corresponding_column(table2.c.otherid) is u1.c.myid
-        
+
         self.assert_compile(
             union(
                 select([table1.c.myid, table1.c.name]),
@@ -1557,7 +1557,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "SELECT thirdtable.userid FROM thirdtable)"
         )
 
-        
+
         s = select([column('foo'), column('bar')])
 
         # ORDER BY's even though not supported by all DB's, are rendered if requested
@@ -1569,9 +1569,9 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             union(s.order_by("foo").self_group(), s.order_by("bar").limit(10).self_group()), 
             "(SELECT foo, bar ORDER BY foo) UNION (SELECT foo, bar ORDER BY bar LIMIT :param_1)",
             {'param_1':10}
-            
+
         )
-        
+
     def test_compound_grouping(self):
         s = select([column('foo'), column('bar')]).select_from('bat')
 
@@ -1580,19 +1580,19 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "((SELECT foo, bar FROM bat UNION SELECT foo, bar FROM bat) "
             "UNION SELECT foo, bar FROM bat) UNION SELECT foo, bar FROM bat"
         )
-        
+
         self.assert_compile(
             union(s, s, s, s),
             "SELECT foo, bar FROM bat UNION SELECT foo, bar "
             "FROM bat UNION SELECT foo, bar FROM bat UNION SELECT foo, bar FROM bat"
         )
-        
+
         self.assert_compile(
             union(s, union(s, union(s, s))),
             "SELECT foo, bar FROM bat UNION (SELECT foo, bar FROM bat "
             "UNION (SELECT foo, bar FROM bat UNION SELECT foo, bar FROM bat))"
         )
-        
+
         self.assert_compile(
             select([s.alias()]),
             'SELECT anon_1.foo, anon_1.bar FROM (SELECT foo, bar FROM bat) AS anon_1'
@@ -1654,8 +1654,8 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                                 "UNION SELECT foo, bar FROM bat) "
                                 "UNION (SELECT foo, bar FROM bat "
                                 "UNION SELECT foo, bar FROM bat)")
-        
-        
+
+
         self.assert_compile(
             union(
                 intersect(s, s),
@@ -1817,9 +1817,9 @@ class SelectTest(TestBase, AssertsCompiledSQL):
 
     def test_binds_no_hash_collision(self):
         """test that construct_params doesn't corrupt dict due to hash collisions"""
-        
+
         total_params = 100000
-        
+
         in_clause = [':in%d' % i for i in range(total_params)]
         params = dict(('in%d' % i, i) for i in range(total_params))
         sql = 'text clause %s' % ', '.join(in_clause)
@@ -1829,14 +1829,14 @@ class SelectTest(TestBase, AssertsCompiledSQL):
         pp = c.construct_params(params)
         eq_(len(set(pp)), total_params, '%s %s' % (len(set(pp)), len(pp)))
         eq_(len(set(pp.values())), total_params)
-        
+
 
     def test_bind_as_col(self):
         t = table('foo', column('id'))
 
         s = select([t, literal('lala').label('hoho')])
         self.assert_compile(s, "SELECT foo.id, :param_1 AS hoho FROM foo")
-        
+
         assert [str(c) for c in s.c] == ["id", "hoho"]
 
     def test_bind_callable(self):
@@ -1846,8 +1846,8 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "x = :key",
             {'x':12}
         )
-        
-        
+
+
     @testing.emits_warning('.*empty sequence.*')
     def test_in(self):
         self.assert_compile(table1.c.myid.in_(['a']),
@@ -1969,7 +1969,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                     ),
             "(mytable.myid, mytable.name) IN ((myothertable.otherid, myothertable.othername))"
         )
-        
+
         self.assert_compile(
             tuple_(table1.c.myid, table1.c.name).in_(
                         select([table2.c.otherid, table2.c.othername])
@@ -1977,8 +1977,8 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "(mytable.myid, mytable.name) IN (SELECT "
             "myothertable.otherid, myothertable.othername FROM myothertable)"
         )
-        
-        
+
+
     def test_cast(self):
         tbl = table('casttest',
                     column('id', Integer),
@@ -2039,7 +2039,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(cast(literal_column('NULL'), Integer),
                             'CAST(NULL AS INTEGER)',
                             dialect=sqlite.dialect())
-        
+
     def test_date_between(self):
         import datetime
         table = Table('dt', metadata,
@@ -2085,15 +2085,15 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             "SELECT op.field FROM op WHERE (op.field = op.field) BETWEEN :param_1 AND :param_2")
         self.assert_compile(table.select(between((table.c.field == table.c.field), False, True)),
             "SELECT op.field FROM op WHERE (op.field = op.field) BETWEEN :param_1 AND :param_2")
-    
+
     def test_associativity(self):
         f = column('f')
         self.assert_compile( f - f, "f - f" )
         self.assert_compile( f - f - f, "(f - f) - f" )
-        
+
         self.assert_compile( (f - f) - f, "(f - f) - f" )
         self.assert_compile( (f - f).label('foo') - f, "(f - f) - f" )
-        
+
         self.assert_compile( f - (f - f), "f - (f - f)" )
         self.assert_compile( f - (f - f).label('foo'), "f - (f - f)" )
 
@@ -2104,54 +2104,54 @@ class SelectTest(TestBase, AssertsCompiledSQL):
         self.assert_compile( f / f - f, "f / f - f" )
         self.assert_compile( (f / f) - f, "f / f - f" )
         self.assert_compile( (f / f).label('foo') - f, "f / f - f" )
-        
+
         # because / more precedent than -
         self.assert_compile( f - (f / f), "f - f / f" )
         self.assert_compile( f - (f / f).label('foo'), "f - f / f" )
         self.assert_compile( f - f / f, "f - f / f" )
         self.assert_compile( (f - f) / f, "(f - f) / f" )
-        
+
         self.assert_compile( ((f - f) / f) - f, "(f - f) / f - f")
         self.assert_compile( (f - f) / (f - f), "(f - f) / (f - f)")
-        
+
         # higher precedence
         self.assert_compile( (f / f) - (f / f), "f / f - f / f")
 
         self.assert_compile( (f / f) - (f - f), "f / f - (f - f)")
         self.assert_compile( (f / f) / (f - f), "(f / f) / (f - f)")
         self.assert_compile( f / (f / (f - f)), "f / (f / (f - f))")
-        
-    
+
+
     def test_delayed_col_naming(self):
         my_str = Column(String)
-        
+
         sel1 = select([my_str])
-        
+
         assert_raises_message(
             exc.InvalidRequestError,
             "Cannot initialize a sub-selectable with this Column",
             lambda: sel1.c
         )
-        
+
         # calling label or as_scalar doesn't compile
-        # anything.  
+        # anything.
         sel2 = select([func.substr(my_str, 2, 3)]).label('my_substr')
-        
+
         assert_raises_message(
             exc.CompileError,
             "Cannot compile Column object until it's 'name' is assigned.",
             str, sel2
         )
-        
+
         sel3 = select([my_str]).as_scalar()
         assert_raises_message(
             exc.CompileError,
             "Cannot compile Column object until it's 'name' is assigned.",
             str, sel3
         )
-        
+
         my_str.name = 'foo'
-        
+
         self.assert_compile(
             sel1,
             "SELECT foo",
@@ -2160,18 +2160,18 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             sel2,
             '(SELECT substr(foo, :substr_2, :substr_3) AS substr_1)',
         )
-        
+
         self.assert_compile(
             sel3,
             "(SELECT foo)"
         )
-        
+
     def test_naming(self):
         f1 = func.hoho(table1.c.name)
         s1 = select([table1.c.myid, table1.c.myid.label('foobar'),
                     f1,
                     func.lala(table1.c.name).label('gg')])
-        
+
         eq_(
             s1.c.keys(),
             ['myid', 'foobar', str(f1), 'gg']
@@ -2179,7 +2179,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
 
         meta = MetaData()
         t1 = Table('mytable', meta, Column('col1', Integer))
-        
+
         exprs = (
             table1.c.myid==12,
             func.hoho(table1.c.myid),
@@ -2197,15 +2197,15 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                 t = col.table
             else:
                 t = table1
-                
+
             s1 = select([col], from_obj=t)
             assert s1.c.keys() == [key], s1.c.keys()
-        
+
             if label:
                 self.assert_compile(s1, "SELECT %s AS %s FROM mytable" % (expr, label))
             else:
                 self.assert_compile(s1, "SELECT %s FROM mytable" % (expr,))
-            
+
             s1 = select([s1])
             if label:
                 self.assert_compile(s1, 
@@ -2220,7 +2220,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                 self.assert_compile(s1, 
                             "SELECT %s FROM (SELECT %s FROM mytable)" % 
                             (expr,expr))
-                
+
     def test_hints(self):
         s = select([table1.c.myid]).with_hint(table1, "test hint %(name)s")
 
@@ -2230,12 +2230,12 @@ class SelectTest(TestBase, AssertsCompiledSQL):
 
         a1 = table1.alias()
         s3 = select([a1.c.myid]).with_hint(a1, "index(%(name)s hint)")
-        
+
         subs4 = select([
             table1, table2
         ]).select_from(table1.join(table2, table1.c.myid==table2.c.otherid)).\
             with_hint(table1, 'hint1')
-        
+
         s4 = select([table3]).select_from(
                         table3.join(
                                 subs4, 
@@ -2243,7 +2243,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                             )
                     ).\
                     with_hint(table3, 'hint3')
-        
+
         subs5 = select([
             table1, table2
         ]).select_from(table1.join(table2, table1.c.myid==table2.c.otherid))
@@ -2255,12 +2255,12 @@ class SelectTest(TestBase, AssertsCompiledSQL):
                     ).\
                     with_hint(table3, 'hint3').\
                     with_hint(table1, 'hint1')
-        
+
         t1 = table('QuotedName', column('col1'))
         s6 = select([t1.c.col1]).where(t1.c.col1>10).with_hint(t1, '%(name)s idx1')
         a2 = t1.alias('SomeName')
         s7 = select([a2.c.col1]).where(a2.c.col1>10).with_hint(a2, '%(name)s idx1')
-        
+
         mysql_d, oracle_d, sybase_d = \
                             mysql.dialect(), \
                             oracle.dialect(), \
@@ -2336,13 +2336,13 @@ class SelectTest(TestBase, AssertsCompiledSQL):
             and_("a", "b"),
             "a AND b"
         )
-        
+
     def test_literal_as_text_nonstring_raise(self):
         assert_raises(exc.ArgumentError,
             and_, ("a",), ("b",)
         )
-        
-        
+
+
 class CRUDTest(TestBase, AssertsCompiledSQL):
     def test_insert(self):
         # generic insert, will create bind params for all columns
@@ -2514,7 +2514,7 @@ class CRUDTest(TestBase, AssertsCompiledSQL):
                                         where(table1.c.name=='somename'), 
                         "DELETE FROM mytable WHERE mytable.myid = :myid_1 "
                         "AND mytable.name = :name_1")
-        
+
     def test_correlated_delete(self):
         # test a non-correlated WHERE clause
         s = select([table2.c.othername], table2.c.otherid == 7)
@@ -2529,26 +2529,26 @@ class CRUDTest(TestBase, AssertsCompiledSQL):
                     "DELETE FROM mytable WHERE mytable.name = (SELECT "
                     "myothertable.othername FROM myothertable WHERE "
                     "myothertable.otherid = mytable.myid)")
-    
+
     def test_binds_that_match_columns(self):
         """test bind params named after column names 
         replace the normal SET/VALUES generation."""
-        
+
         t = table('foo', column('x'), column('y'))
 
         u = t.update().where(t.c.x==bindparam('x'))
-    
+
         assert_raises(exc.CompileError, u.compile)
-        
+
         self.assert_compile(u, "UPDATE foo SET  WHERE foo.x = :x", params={})
 
         assert_raises(exc.CompileError, u.values(x=7).compile)
-        
+
         self.assert_compile(u.values(y=7), "UPDATE foo SET y=:y WHERE foo.x = :x")
-        
+
         assert_raises(exc.CompileError, u.values(x=7).compile, column_keys=['x', 'y'])
         assert_raises(exc.CompileError, u.compile, column_keys=['x', 'y'])
-        
+
         self.assert_compile(u.values(x=3 + bindparam('x')), 
                             "UPDATE foo SET x=(:param_1 + :x) WHERE foo.x = :x")
 
@@ -2574,7 +2574,7 @@ class CRUDTest(TestBase, AssertsCompiledSQL):
 
         i = t.insert().values(x=3 + bindparam('y'), y=5)
         assert_raises(exc.CompileError, i.compile)
-        
+
         i = t.insert().values(x=3 + bindparam('x2'))
         self.assert_compile(i, "INSERT INTO foo (x) VALUES ((:param_1 + :x2))")
         self.assert_compile(i, "INSERT INTO foo (x) VALUES ((:param_1 + :x2))", params={})
@@ -2582,11 +2582,11 @@ class CRUDTest(TestBase, AssertsCompiledSQL):
                                     params={'x':1, 'y':2})
         self.assert_compile(i, "INSERT INTO foo (x, y) VALUES ((:param_1 + :x2), :y)",
                                     params={'x2':1, 'y':2})
-    
+
     def test_labels_no_collision(self):
-        
+
         t = table('foo', column('id'), column('foo_id'))
-        
+
         self.assert_compile(
             t.update().where(t.c.id==5),
             "UPDATE foo SET id=:id, foo_id=:foo_id WHERE foo.id = :id_1"
@@ -2596,7 +2596,7 @@ class CRUDTest(TestBase, AssertsCompiledSQL):
             t.update().where(t.c.id==bindparam(key=t.c.id._label)),
             "UPDATE foo SET id=:id, foo_id=:foo_id WHERE foo.id = :foo_id_1"
         )
-        
+
 class InlineDefaultTest(TestBase, AssertsCompiledSQL):
     def test_insert(self):
         m = MetaData()
@@ -2634,7 +2634,7 @@ class SchemaTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(table4.select(), 
                 "SELECT remote_owner.remotetable.rem_id, remote_owner.remotetable.datatype_id,"
                 " remote_owner.remotetable.value FROM remote_owner.remotetable")
-                
+
         self.assert_compile(table4.select(and_(table4.c.datatype_id==7, table4.c.value=='hi')),
                 "SELECT remote_owner.remotetable.rem_id, remote_owner.remotetable.datatype_id,"
                 " remote_owner.remotetable.value FROM remote_owner.remotetable WHERE "
@@ -2664,7 +2664,7 @@ class SchemaTest(TestBase, AssertsCompiledSQL):
                 ' "dbo.remote_owner".remotetable.value AS dbo_remote_owner_remotetable_value FROM'
                 ' "dbo.remote_owner".remotetable'
         )
-        
+
     def test_alias(self):
         a = alias(table4, 'remtable')
         self.assert_compile(a.select(a.c.datatype_id==7), 
index 56c5c62052ec9f4a1aa5c05a2d8a02b6015a63b8..fb07bf437e9949c50c86785391267f11e30c3fb5 100644 (file)
@@ -36,10 +36,10 @@ class ConstraintTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
     def test_double_fk_usage_raises(self):
         f = ForeignKey('b.id')
-        
+
         Column('x', Integer, f)
         assert_raises(exc.InvalidRequestError, Column, "y", Integer, f)
-        
+
     def test_circular_constraint(self):
         a = Table("a", metadata,
             Column('id', Integer, primary_key=True),
@@ -192,22 +192,22 @@ class ConstraintTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
                 ('sometable', 'this_name_is_too_long', 'ix_sometable_t_09aa'),
                 ('sometable', 'this_name_alsois_long', 'ix_sometable_t_3cf1'),
             ]:
-        
+
                 t1 = Table(tname, MetaData(), 
                             Column(cname, Integer, index=True),
                         )
                 ix1 = list(t1.indexes)[0]
-        
+
                 self.assert_compile(
                     schema.CreateIndex(ix1),
                     "CREATE INDEX %s "
                     "ON %s (%s)" % (exp, tname, cname),
                     dialect=dialect
                 )
-        
+
         dialect.max_identifier_length = 22
         dialect.max_index_name_length = None
-        
+
         t1 = Table('t', MetaData(), Column('c', Integer))
         assert_raises(
             exc.IdentifierError,
@@ -217,7 +217,7 @@ class ConstraintTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
             dialect=dialect
         )
 
-    
+
 class ConstraintCompilationTest(TestBase, AssertsCompiledSQL):
 
     def _test_deferrable(self, constraint_factory):
@@ -225,11 +225,11 @@ class ConstraintCompilationTest(TestBase, AssertsCompiledSQL):
                   Column('a', Integer),
                   Column('b', Integer),
                   constraint_factory(deferrable=True))
-                  
+
         sql = str(schema.CreateTable(t).compile(bind=testing.db))
         assert 'DEFERRABLE' in sql, sql
         assert 'NOT DEFERRABLE' not in sql, sql
-        
+
         t = Table('tbl', MetaData(),
                   Column('a', Integer),
                   Column('b', Integer),
@@ -291,18 +291,18 @@ class ConstraintCompilationTest(TestBase, AssertsCompiledSQL):
                          CheckConstraint('a < b',
                                          deferrable=True,
                                          initially='DEFERRED')))
-        
+
         self.assert_compile(
             schema.CreateTable(t),
             "CREATE TABLE tbl (a INTEGER, b INTEGER CHECK (a < b) DEFERRABLE INITIALLY DEFERRED)"
         )
-    
+
     def test_use_alter(self):
         m = MetaData()
         t = Table('t', m,
                   Column('a', Integer),
         )
-        
+
         t2 = Table('t2', m,
                 Column('a', Integer, ForeignKey('t.a', use_alter=True, name='fk_ta')),
                 Column('b', Integer, ForeignKey('t.a', name='fk_tb')), # to ensure create ordering ...
@@ -320,25 +320,25 @@ class ConstraintCompilationTest(TestBase, AssertsCompiledSQL):
             'DROP TABLE t2', 
             'DROP TABLE t'
         ])
-        
-        
+
+
     def test_add_drop_constraint(self):
         m = MetaData()
-        
+
         t = Table('tbl', m,
                   Column('a', Integer),
                   Column('b', Integer)
         )
-        
+
         t2 = Table('t2', m,
                 Column('a', Integer),
                 Column('b', Integer)
         )
-        
+
         constraint = CheckConstraint('a < b',name="my_test_constraint",
                                         deferrable=True,initially='DEFERRED', table=t)
 
-        
+
         # before we create an AddConstraint,
         # the CONSTRAINT comes out inline
         self.assert_compile(
@@ -397,13 +397,13 @@ class ConstraintCompilationTest(TestBase, AssertsCompiledSQL):
             schema.AddConstraint(constraint),
             "ALTER TABLE t2 ADD CONSTRAINT uq_cst UNIQUE (a, b)"
         )
-        
+
         constraint = UniqueConstraint(t2.c.a, t2.c.b, name="uq_cs2")
         self.assert_compile(
             schema.AddConstraint(constraint),
             "ALTER TABLE t2 ADD CONSTRAINT uq_cs2 UNIQUE (a, b)"
         )
-        
+
         assert t.c.a.primary_key is False
         constraint = PrimaryKeyConstraint(t.c.a)
         assert t.c.a.primary_key is True
@@ -411,5 +411,5 @@ class ConstraintCompilationTest(TestBase, AssertsCompiledSQL):
             schema.AddConstraint(constraint),
             "ALTER TABLE tbl ADD PRIMARY KEY (a)"
         )
-    
-        
+
+
index 7ec43f8d2b30fd1166ed38a64947ccd92ef0aacf..31759a7098bb6984db3f32c1df3facaffeadddcf 100644 (file)
@@ -147,7 +147,7 @@ class DefaultTest(testing.TestBase):
             assert_raises_message(sa.exc.ArgumentError,
                                      ex_msg,
                                      sa.ColumnDefault, fn)
-    
+
     def test_arg_signature(self):
         def fn1(): pass
         def fn2(): pass
@@ -277,7 +277,7 @@ class DefaultTest(testing.TestBase):
         assert r.lastrow_has_defaults()
         eq_(set(r.context.postfetch_cols),
             set([t.c.col3, t.c.col5, t.c.col4, t.c.col6]))
-        
+
         eq_(t.select(t.c.col1==54).execute().fetchall(),
             [(54, 'imthedefault', f, ts, ts, ctexec, True, False,
               12, today, None)])
@@ -301,7 +301,7 @@ class DefaultTest(testing.TestBase):
               12, today, 'py'),
              (53, 'imthedefault', f, ts, ts, ctexec, True, False,
               12, today, 'py')])
-    
+
     def test_missing_many_param(self):
         assert_raises_message(exc.InvalidRequestError, 
             "A value is required for bind parameter 'col7', in parameter group 1",
@@ -310,7 +310,7 @@ class DefaultTest(testing.TestBase):
             {'col4':7, 'col8':19},
             {'col4':7, 'col7':12, 'col8':19},
         )
-        
+
     def test_insert_values(self):
         t.insert(values={'col3':50}).execute()
         l = t.select().execute()
@@ -366,7 +366,7 @@ class DefaultTest(testing.TestBase):
         l = l.first()
         eq_(55, l['col3'])
 
-    
+
 class PKDefaultTest(_base.TablesTest):
     __requires__ = ('subqueries',)
 
@@ -379,14 +379,14 @@ class PKDefaultTest(_base.TablesTest):
               Column('id', Integer, primary_key=True,
                      default=sa.select([func.max(t2.c.nextid)]).as_scalar()),
               Column('data', String(30)))
-    
+
     @testing.requires.returning
     def test_with_implicit_returning(self):
         self._test(True)
-        
+
     def test_regular(self):
         self._test(False)
-        
+
     @testing.resolve_artifact_names
     def _test(self, returning):
         if not returning and not testing.db.dialect.implicit_returning:
@@ -442,7 +442,7 @@ class PKIncrementTest(_base.TablesTest):
         ids.add(last)
 
         eq_(ids, set([1,2,3,4]))
-        
+
         eq_(list(bind.execute(aitable.select().order_by(aitable.c.id))),
             [(1, 1, None), (2, None, 'row 2'), (3, 3, 'row 3'), (4, 4, None)])
 
@@ -477,7 +477,7 @@ class EmptyInsertTest(testing.TestBase):
         t1 = Table('t1', metadata,
                 Column('is_true', Boolean, server_default=('1')))
         metadata.create_all()
-        
+
         try:
             result = t1.insert().execute()
             eq_(1, select([func.count(text('*'))], from_obj=t1).scalar())
@@ -588,7 +588,7 @@ class SequenceTest(testing.TestBase, testing.AssertsCompiledSQL):
             "DROP SEQUENCE foo_seq",
             use_default_dialect=True,
         )
-        
+
 
     @testing.fails_on('firebird', 'no FB support for start/increment')
     @testing.requires.sequences
@@ -605,10 +605,10 @@ class SequenceTest(testing.TestBase, testing.AssertsCompiledSQL):
                 start = seq.start or 1
                 inc = seq.increment or 1
                 assert values == list(xrange(start, start + inc * 3, inc))
-                
+
             finally:
                 seq.drop(testing.db)
-        
+
     @testing.requires.sequences
     def test_seq_nonpk(self):
         """test sequences fire off as defaults on non-pk columns"""
index 0fb2ca5f7f8eabda2af45b7f61303457daa0ef76..13116a4bbc3545f8d6c2906d43cc57df0dbc876c 100644 (file)
@@ -26,8 +26,8 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                 self.assert_compile(func.nosuchfunction(), "nosuchfunction", dialect=dialect)
             else:
                 self.assert_compile(func.nosuchfunction(), "nosuchfunction()", dialect=dialect)
-            
-            # test generic function compile    
+
+            # test generic function compile
             class fake_func(GenericFunction):
                 __return_type__ = sqltypes.Integer
 
@@ -39,14 +39,14 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                             "fake_func(%s)" % 
                             bindtemplate % {'name':'param_1', 'position':1}, 
                             dialect=dialect)
-            
+
     def test_use_labels(self):
         self.assert_compile(select([func.foo()], use_labels=True), 
             "SELECT foo() AS foo_1"
         )
     def test_underscores(self):
         self.assert_compile(func.if_(), "if()")
-        
+
     def test_generic_now(self):
         assert isinstance(func.now().type, sqltypes.DateTime)
 
@@ -69,10 +69,10 @@ class CompileTest(TestBase, AssertsCompiledSQL):
             ('random', oracle.dialect())
         ]:
             self.assert_compile(func.random(), ret, dialect=dialect)
-    
+
     def test_namespacing_conflicts(self):
         self.assert_compile(func.text('foo'), 'text(:text_1)')
-        
+
     def test_generic_count(self):
         assert isinstance(func.count().type, sqltypes.Integer)
 
@@ -101,7 +101,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
             assert True
 
     def test_return_type_detection(self):
-        
+
         for fn in [func.coalesce, func.max, func.min, func.sum]:
             for args, type_ in [
                             ((datetime.date(2007, 10, 5), 
@@ -113,7 +113,7 @@ class CompileTest(TestBase, AssertsCompiledSQL):
                                 datetime.datetime(2005, 10, 15, 14, 45, 33)), sqltypes.DateTime)
                         ]:
                 assert isinstance(fn(*args).type, type_), "%s / %s" % (fn(), type_)
-        
+
         assert isinstance(func.concat("foo", "bar").type, sqltypes.String)
 
 
@@ -193,7 +193,7 @@ class ExecuteTest(TestBase):
     @engines.close_first
     def tearDown(self):
         pass
-        
+
     def test_standalone_execute(self):
         x = testing.db.func.current_date().execute().scalar()
         y = testing.db.func.current_date().select().execute().scalar()
@@ -208,10 +208,10 @@ class ExecuteTest(TestBase):
     def test_conn_execute(self):
         from sqlalchemy.sql.expression import FunctionElement
         from sqlalchemy.ext.compiler import compiles
-        
+
         class myfunc(FunctionElement):
             type = Date()
-        
+
         @compiles(myfunc)
         def compile(elem, compiler, **kw):
             return compiler.process(func.current_date())
@@ -229,17 +229,17 @@ class ExecuteTest(TestBase):
     def test_exec_options(self):
         f = func.foo()
         eq_(f._execution_options, {})
-        
+
         f = f.execution_options(foo='bar')
         eq_(f._execution_options, {'foo':'bar'})
         s = f.select()
         eq_(s._execution_options, {'foo':'bar'})
-        
+
         ret = testing.db.execute(func.now().execution_options(foo='bar'))
         eq_(ret.context.execution_options, {'foo':'bar'})
         ret.close()
-        
-        
+
+
     @engines.close_first
     def test_update(self):
         """
index e129f69c4d35da1a0aae2d06340191c9f7e9d28b..627736370dccfad095d5f2126f861b2bfa4d6a18 100644 (file)
@@ -27,7 +27,7 @@ class TraversalTest(TestBase, AssertsExecutionResults):
                 return other is self
 
             __hash__ = ClauseElement.__hash__
-            
+
             def __eq__(self, other):
                 return other.expr == self.expr
 
@@ -100,7 +100,7 @@ class TraversalTest(TestBase, AssertsExecutionResults):
         s2 = vis.traverse(struct)
         assert struct == s2
         assert not struct.is_other(s2)
-    
+
     def test_no_clone(self):
         struct = B(A("expr1"), A("expr2"), B(A("expr1b"), A("expr2b")), A("expr3"))
 
@@ -151,9 +151,9 @@ class TraversalTest(TestBase, AssertsExecutionResults):
 
         class CustomObj(Column):
             pass
-            
+
         assert CustomObj.__visit_name__ == Column.__visit_name__ == 'column'
-        
+
         foo, bar = CustomObj('foo', String), CustomObj('bar', String)
         bin = foo == bar
         s = set(ClauseVisitor().iterate(bin))
@@ -193,7 +193,7 @@ class ClauseTest(TestBase, AssertsCompiledSQL):
         f = sql_util.ClauseAdapter(a).traverse(f)
 
         self.assert_compile(select([f]), "SELECT t1_1.col1 * :col1_1 AS anon_1 FROM t1 AS t1_1")
-        
+
     def test_join(self):
         clause = t1.join(t2, t1.c.col2==t2.c.col2)
         c1 = str(clause)
@@ -206,20 +206,20 @@ class ClauseTest(TestBase, AssertsCompiledSQL):
         clause2 = Vis().traverse(clause)
         assert c1 == str(clause)
         assert str(clause2) == str(t1.join(t2, t1.c.col2==t2.c.col3))
-    
+
     def test_aliased_column_adapt(self):
         clause = t1.select()
-        
+
         aliased = t1.select().alias()
         aliased2 = t1.alias()
  
         adapter = sql_util.ColumnAdapter(aliased)
-        
+
         f = select([
             adapter.columns[c]
             for c in aliased2.c
         ]).select_from(aliased)
-    
+
         s = select([aliased2]).select_from(aliased)
         eq_(str(s), str(f))
  
@@ -230,8 +230,8 @@ class ClauseTest(TestBase, AssertsCompiledSQL):
             str(select([func.count(aliased2.c.col1)]).select_from(aliased)),
             str(f)
         )
-        
-        
+
+
     def test_text(self):
         clause = text("select * from table where foo=:bar", bindparams=[bindparam('bar')])
         c1 = str(clause)
@@ -288,7 +288,7 @@ class ClauseTest(TestBase, AssertsCompiledSQL):
         print str(s5)
         assert str(s5) == s5_assert
         assert str(s4) == s4_assert
-    
+
     def test_union(self):
         u = union(t1.select(), t2.select())
         u2 = CloningVisitor().traverse(u)
@@ -300,27 +300,27 @@ class ClauseTest(TestBase, AssertsCompiledSQL):
         u2 = CloningVisitor().traverse(u)
         assert str(u) == str(u2)
         assert [str(c) for c in u2.c] == cols
-        
+
         s1 = select([t1], t1.c.col1 == bindparam('id_param'))
         s2 = select([t2])
         u = union(s1, s2)
-        
+
         u2 = u.params(id_param=7)
         u3 = u.params(id_param=10)
         assert str(u) == str(u2) == str(u3)
         assert u2.compile().params == {'id_param':7}
         assert u3.compile().params == {'id_param':10}
-    
+
     def test_in(self):
         expr = t1.c.col1.in_(['foo', 'bar'])
         expr2 = CloningVisitor().traverse(expr)
         assert str(expr) == str(expr2)
-        
+
     def test_adapt_union(self):
         u = union(t1.select().where(t1.c.col1==4), t1.select().where(t1.c.col1==5)).alias()
-        
+
         assert sql_util.ClauseAdapter(u).traverse(t1) is u
-        
+
     def test_binds(self):
         """test that unique bindparams change their name upon clone() to prevent conflicts"""
 
@@ -340,17 +340,17 @@ class ClauseTest(TestBase, AssertsCompiledSQL):
         "table1.col3 AS col3 FROM table1 WHERE table1.col1 = :col1_1) AS anon_1, "\
         "(SELECT table1.col1 AS col1, table1.col2 AS col2, table1.col3 AS col3 FROM table1 WHERE table1.col1 = :col1_2) AS anon_2 "\
         "WHERE anon_1.col2 = anon_2.col2")
-    
+
     def test_extract(self):
         s = select([extract('foo', t1.c.col1).label('col1')])
         self.assert_compile(s, "SELECT EXTRACT(foo FROM table1.col1) AS col1 FROM table1")
-        
+
         s2 = CloningVisitor().traverse(s).alias()
         s3 = select([s2.c.col1])
         self.assert_compile(s, "SELECT EXTRACT(foo FROM table1.col1) AS col1 FROM table1")
         self.assert_compile(s3, "SELECT anon_1.col1 FROM (SELECT EXTRACT(foo FROM table1.col1) AS col1 FROM table1) AS anon_1")
-        
-        
+
+
     @testing.emits_warning('.*replaced by another column with the same key')
     def test_alias(self):
         subq = t2.select().alias('subq')
@@ -372,7 +372,7 @@ class ClauseTest(TestBase, AssertsCompiledSQL):
         s = select([t1.c.col1, subq.c.col1], from_obj=[t1, subq, t1.join(subq, t1.c.col1==subq.c.col2)])
         s5 = CloningVisitor().traverse(s)
         assert orig == str(s) == str(s5)
-        
+
     def test_correlated_select(self):
         s = select(['*'], t1.c.col1==t2.c.col1, from_obj=[t1, t2]).correlate(t2)
         class Vis(CloningVisitor):
@@ -380,32 +380,32 @@ class ClauseTest(TestBase, AssertsCompiledSQL):
                 select.append_whereclause(t1.c.col2==7)
 
         self.assert_compile(Vis().traverse(s), "SELECT * FROM table1 WHERE table1.col1 = table2.col1 AND table1.col2 = :col2_1")
-    
+
     def test_this_thing(self):
         s = select([t1]).where(t1.c.col1=='foo').alias()
         s2 = select([s.c.col1])
-        
+
         self.assert_compile(s2, "SELECT anon_1.col1 FROM (SELECT table1.col1 AS col1, table1.col2 AS col2, table1.col3 AS col3 FROM table1 WHERE table1.col1 = :col1_1) AS anon_1")
         t1a = t1.alias()
         s2 = sql_util.ClauseAdapter(t1a).traverse(s2)
         self.assert_compile(s2, "SELECT anon_1.col1 FROM (SELECT table1_1.col1 AS col1, table1_1.col2 AS col2, table1_1.col3 AS col3 FROM table1 AS table1_1 WHERE table1_1.col1 = :col1_1) AS anon_1")
-        
+
     def test_select_fromtwice(self):
         t1a = t1.alias()
-        
+
         s = select([1], t1.c.col1==t1a.c.col1, from_obj=t1a).correlate(t1)
         self.assert_compile(s, "SELECT 1 FROM table1 AS table1_1 WHERE table1.col1 = table1_1.col1")
-        
+
         s = CloningVisitor().traverse(s)
         self.assert_compile(s, "SELECT 1 FROM table1 AS table1_1 WHERE table1.col1 = table1_1.col1")
-        
+
         s = select([t1]).where(t1.c.col1=='foo').alias()
-        
+
         s2 = select([1], t1.c.col1==s.c.col1, from_obj=s).correlate(t1)
         self.assert_compile(s2, "SELECT 1 FROM (SELECT table1.col1 AS col1, table1.col2 AS col2, table1.col3 AS col3 FROM table1 WHERE table1.col1 = :col1_1) AS anon_1 WHERE table1.col1 = anon_1.col1")
         s2 = ReplacingCloningVisitor().traverse(s2)
         self.assert_compile(s2, "SELECT 1 FROM (SELECT table1.col1 AS col1, table1.col2 AS col2, table1.col3 AS col3 FROM table1 WHERE table1.col1 = :col1_1) AS anon_1 WHERE table1.col1 = anon_1.col1")
-        
+
 class ClauseAdapterTest(TestBase, AssertsCompiledSQL):
     @classmethod
     def setup_class(cls):
@@ -446,7 +446,7 @@ class ClauseAdapterTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(select(['*'], t2alias.c.col1==s), "SELECT * FROM table2 AS t2alias WHERE t2alias.col1 = (SELECT * FROM table1 AS t1alias)")
         s = CloningVisitor().traverse(s)
         self.assert_compile(select(['*'], t2alias.c.col1==s), "SELECT * FROM table2 AS t2alias WHERE t2alias.col1 = (SELECT * FROM table1 AS t1alias)")
-        
+
         s = select(['*']).where(t1.c.col1==t2.c.col1).as_scalar()
         self.assert_compile(select([t1.c.col1, s]), "SELECT table1.col1, (SELECT * FROM table2 WHERE table1.col1 = table2.col1) AS anon_1 FROM table1")
         vis = sql_util.ClauseAdapter(t1alias)
@@ -478,7 +478,7 @@ class ClauseAdapterTest(TestBase, AssertsCompiledSQL):
         j1 = addresses.join(ualias, addresses.c.user_id==ualias.c.id)
 
         self.assert_compile(sql_util.ClauseAdapter(j1).traverse(s), "SELECT count(addresses.id) AS count_1 FROM addresses WHERE users_1.id = addresses.user_id")
-        
+
     def test_table_to_alias(self):
 
         t1alias = t1.alias('t1alias')
@@ -543,7 +543,7 @@ class ClauseAdapterTest(TestBase, AssertsCompiledSQL):
         a = Table('a', m, Column('x', Integer), Column('y', Integer))
         b = Table('b', m, Column('x', Integer), Column('y', Integer))
         c = Table('c', m, Column('x', Integer), Column('y', Integer))
-        
+
         # force a recursion overflow, by linking a.c.x<->c.c.x, and
         # asking for a nonexistent col.  corresponding_column should prevent
         # endless depth.
@@ -557,13 +557,13 @@ class ClauseAdapterTest(TestBase, AssertsCompiledSQL):
         c = Table('c', m, Column('x', Integer), Column('y', Integer))
 
         alias = select([a]).select_from(a.join(b, a.c.x==b.c.x)).alias()
-        
+
         # two levels of indirection from c.x->b.x->a.x, requires recursive 
         # corresponding_column call
         adapt = sql_util.ClauseAdapter(alias, equivalents= {b.c.x: set([ a.c.x]), c.c.x:set([b.c.x])})
         assert adapt._corresponding_column(a.c.x, False) is alias.c.x
         assert adapt._corresponding_column(c.c.x, False) is alias.c.x
-        
+
     def test_join_to_alias(self):
         metadata = MetaData()
         a = Table('a', metadata,
@@ -642,13 +642,13 @@ class ClauseAdapterTest(TestBase, AssertsCompiledSQL):
             "(SELECT table1.col1 AS col1, table1.col2 AS col2, table1.col3 AS col3 FROM table1) AS foo LIMIT :param_1 OFFSET :param_2) AS anon_1 "\
             "LEFT OUTER JOIN table1 AS bar ON anon_1.col1 = bar.col1",
             {'param_1':5, 'param_2':10})
-    
+
     def test_functions(self):
         self.assert_compile(sql_util.ClauseAdapter(t1.alias()).traverse(func.count(t1.c.col1)), "count(table1_1.col1)")
 
         s = select([func.count(t1.c.col1)])
         self.assert_compile(sql_util.ClauseAdapter(t1.alias()).traverse(s), "SELECT count(table1_1.col1) AS count_1 FROM table1 AS table1_1")
-        
+
     def test_recursive(self):
         metadata = MetaData()
         a = Table('a', metadata,
@@ -670,8 +670,8 @@ class ClauseAdapterTest(TestBase, AssertsCompiledSQL):
         u = union(
             a.join(b).select().apply_labels(),
             a.join(d).select().apply_labels()
-        ).alias()    
-        
+        ).alias()
+
         self.assert_compile(
             sql_util.ClauseAdapter(u).traverse(select([c.c.bid]).where(c.c.bid==u.c.b_aid)),
             "SELECT c.bid "\
@@ -687,16 +687,16 @@ class SpliceJoinsTest(TestBase, AssertsCompiledSQL):
         global table1, table2, table3, table4
         def _table(name):
             return table(name, column("col1"), column("col2"),column("col3"))
-        
-        table1, table2, table3, table4 = [_table(name) for name in ("table1", "table2", "table3", "table4")]    
+
+        table1, table2, table3, table4 = [_table(name) for name in ("table1", "table2", "table3", "table4")]
 
     def test_splice(self):
         (t1, t2, t3, t4) = (table1, table2, table1.alias(), table2.alias())
-        
+
         j = t1.join(t2, t1.c.col1==t2.c.col1).join(t3, t2.c.col1==t3.c.col1).join(t4, t4.c.col1==t1.c.col1)
-        
+
         s = select([t1]).where(t1.c.col2<5).alias()
-        
+
         self.assert_compile(sql_util.splice_joins(s, j), 
             "(SELECT table1.col1 AS col1, table1.col2 AS col2, "\
             "table1.col3 AS col3 FROM table1 WHERE table1.col2 < :col2_1) AS anon_1 "\
@@ -705,12 +705,12 @@ class SpliceJoinsTest(TestBase, AssertsCompiledSQL):
 
     def test_stop_on(self):
         (t1, t2, t3) = (table1, table2, table3)
-        
+
         j1= t1.join(t2, t1.c.col1==t2.c.col1)
         j2 = j1.join(t3, t2.c.col1==t3.c.col1)
-        
+
         s = select([t1]).select_from(j1).alias()
-        
+
         self.assert_compile(sql_util.splice_joins(s, j2), 
             "(SELECT table1.col1 AS col1, table1.col2 AS col2, table1.col3 AS col3 FROM table1 JOIN table2 "\
             "ON table1.col1 = table2.col1) AS anon_1 JOIN table2 ON anon_1.col1 = table2.col1 JOIN table3 "\
@@ -720,27 +720,27 @@ class SpliceJoinsTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(sql_util.splice_joins(s, j2, j1), 
             "(SELECT table1.col1 AS col1, table1.col2 AS col2, table1.col3 AS col3 FROM table1 "\
             "JOIN table2 ON table1.col1 = table2.col1) AS anon_1 JOIN table3 ON table2.col1 = table3.col1")
-    
+
     def test_splice_2(self):
         t2a = table2.alias()
         t3a = table3.alias()
         j1 = table1.join(t2a, table1.c.col1==t2a.c.col1).join(t3a, t2a.c.col2==t3a.c.col2)
-        
+
         t2b = table4.alias()
         j2 = table1.join(t2b, table1.c.col3==t2b.c.col3)
-        
+
         self.assert_compile(sql_util.splice_joins(table1, j1), 
             "table1 JOIN table2 AS table2_1 ON table1.col1 = table2_1.col1 "\
             "JOIN table3 AS table3_1 ON table2_1.col2 = table3_1.col2")
-            
+
         self.assert_compile(sql_util.splice_joins(table1, j2), "table1 JOIN table4 AS table4_1 ON table1.col3 = table4_1.col3")
 
         self.assert_compile(sql_util.splice_joins(sql_util.splice_joins(table1, j1), j2), 
             "table1 JOIN table2 AS table2_1 ON table1.col1 = table2_1.col1 "\
             "JOIN table3 AS table3_1 ON table2_1.col2 = table3_1.col2 "\
             "JOIN table4 AS table4_1 ON table1.col3 = table4_1.col3")
-    
-        
+
+
 class SelectTest(TestBase, AssertsCompiledSQL):
     """tests the generative capability of Select"""
 
@@ -838,7 +838,7 @@ class SelectTest(TestBase, AssertsCompiledSQL):
         assert s._execution_options == dict(foo='bar')
         # s2 should have its execution_options based on s, though.
         assert s2._execution_options == dict(foo='bar', bar='baz')
-    
+
     # this feature not available yet
     def _NOTYET_test_execution_options_in_text(self):
         s = text('select 42', execution_options=dict(foo='bar'))
index 0f84c30a0f37471dfa745adcca1e8a5ab5b89cc7..9160aa3ee507d13e9c13af4d3e61028defe69f3e 100644 (file)
@@ -51,7 +51,7 @@ class LongLabelsTest(TestBase, AssertsCompiledSQL):
         assert_raises(exceptions.IdentifierError, m.drop_all)
         assert_raises(exceptions.IdentifierError, t1.create)
         assert_raises(exceptions.IdentifierError, t1.drop)
-        
+
     def test_result(self):
         table1.insert().execute(**{"this_is_the_primarykey_column":1, "this_is_the_data_column":"data1"})
         table1.insert().execute(**{"this_is_the_primarykey_column":2, "this_is_the_data_column":"data2"})
@@ -82,7 +82,7 @@ class LongLabelsTest(TestBase, AssertsCompiledSQL):
             (1, "data1"),
             (2, "data2"),
         ], repr(result)
-  
+
         @testing.requires.offset
         def go():
             r = s.limit(2).offset(1).execute()
@@ -94,7 +94,7 @@ class LongLabelsTest(TestBase, AssertsCompiledSQL):
                 (3, "data3"),
             ], repr(result)
         go()
-        
+
     def test_table_alias_names(self):
         if testing.against('oracle'):
             self.assert_compile(
@@ -113,7 +113,7 @@ class LongLabelsTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(
             select([table1, ta]).select_from(table1.join(ta, table1.c.this_is_the_data_column==ta.c.this_is_the_data_column)).\
                         where(ta.c.this_is_the_data_column=='data3'),
-                        
+
             "SELECT some_large_named_table.this_is_the_primarykey_column, some_large_named_table.this_is_the_data_column, "
             "table_with_exactly_29_c_1.this_is_the_primarykey_column, table_with_exactly_29_c_1.this_is_the_data_column FROM "
             "some_large_named_table JOIN table_with_exactly_29_characs AS table_with_exactly_29_c_1 ON "
@@ -121,17 +121,17 @@ class LongLabelsTest(TestBase, AssertsCompiledSQL):
             "WHERE table_with_exactly_29_c_1.this_is_the_data_column = :this_is_the_data_column_1",
             dialect=dialect
         )
-        
+
         table2.insert().execute(
             {"this_is_the_primarykey_column":1, "this_is_the_data_column":"data1"},
             {"this_is_the_primarykey_column":2, "this_is_the_data_column":"data2"},
             {"this_is_the_primarykey_column":3, "this_is_the_data_column":"data3"},
             {"this_is_the_primarykey_column":4, "this_is_the_data_column":"data4"},
         )
-        
+
         r = table2.alias().select().execute()
         assert r.fetchall() == [(x, "data%d" % x) for x in range(1, 5)]
-        
+
     def test_colbinds(self):
         table1.insert().execute(**{"this_is_the_primarykey_column":1, "this_is_the_data_column":"data1"})
         table1.insert().execute(**{"this_is_the_primarykey_column":2, "this_is_the_data_column":"data2"})
@@ -201,5 +201,5 @@ class LongLabelsTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(x, "SELECT _1.this_is_the_primarykey_column AS _1, _1.this_is_the_data_column AS _2 FROM "
             "(SELECT some_large_named_table.this_is_the_primarykey_column AS _3, some_large_named_table.this_is_the_data_column AS _4 "
             "FROM some_large_named_table WHERE some_large_named_table.this_is_the_primarykey_column = :_1) AS _1", dialect=compile_dialect)
-        
-        
+
+
index c5ef481542ba42c16b74f1d75dbc417f0e94bf31..75eac9ee8aed17a7a12b5d4b3db0ca9d145cb000 100644 (file)
@@ -32,7 +32,7 @@ class MetaDataTest(TestBase, ComparesTables):
         t2 = Table('t2', metadata, Column('x', Integer), schema='foo')
         t3 = Table('t2', MetaData(), Column('x', Integer))
         t4 = Table('t1', MetaData(), Column('x', Integer), schema='foo')
-        
+
         assert "t1" in metadata
         assert "foo.t2" in metadata
         assert "t2" not in metadata
@@ -41,7 +41,7 @@ class MetaDataTest(TestBase, ComparesTables):
         assert t2 in metadata
         assert t3 not in metadata
         assert t4 not in metadata
-        
+
     def test_uninitialized_column_copy(self):
         for col in [
             Column('foo', String(), nullable=False),
@@ -76,24 +76,24 @@ class MetaDataTest(TestBase, ComparesTables):
             cx = c1.copy()
             t = Table('foo%d' % i, m, cx)
         eq_(msgs, ['attach foo0.foo', 'attach foo1.foo', 'attach foo2.foo'])
-        
+
     def test_schema_collection_add(self):
         metadata = MetaData()
-        
+
         t1 = Table('t1', metadata, Column('x', Integer), schema='foo')
         t2 = Table('t2', metadata, Column('x', Integer), schema='bar')
         t3 = Table('t3', metadata, Column('x', Integer))
-        
+
         eq_(metadata._schemas, set(['foo', 'bar']))
         eq_(len(metadata.tables), 3)
-    
+
     def test_schema_collection_remove(self):
         metadata = MetaData()
-        
+
         t1 = Table('t1', metadata, Column('x', Integer), schema='foo')
         t2 = Table('t2', metadata, Column('x', Integer), schema='bar')
         t3 = Table('t3', metadata, Column('x', Integer), schema='bar')
-        
+
         metadata.remove(t3)
         eq_(metadata._schemas, set(['foo', 'bar']))
         eq_(len(metadata.tables), 2)
@@ -101,28 +101,28 @@ class MetaDataTest(TestBase, ComparesTables):
         metadata.remove(t1)
         eq_(metadata._schemas, set(['bar']))
         eq_(len(metadata.tables), 1)
-    
+
     def test_schema_collection_remove_all(self):
         metadata = MetaData()
-        
+
         t1 = Table('t1', metadata, Column('x', Integer), schema='foo')
         t2 = Table('t2', metadata, Column('x', Integer), schema='bar')
 
         metadata.clear()
         eq_(metadata._schemas, set())
         eq_(len(metadata.tables), 0)
-    
+
     def test_metadata_tables_immutable(self):
         metadata = MetaData()
-        
+
         t1 = Table('t1', metadata, Column('x', Integer))
         assert 't1' in metadata.tables
-        
+
         assert_raises(
             TypeError,
             lambda: metadata.tables.pop('t1')
         )
-    
+
     @testing.provide_metadata
     def test_dupe_tables(self):
         t1 = Table('table1', metadata, 
@@ -143,28 +143,28 @@ class MetaDataTest(TestBase, ComparesTables):
             "Table object.",
             go
         )
-    
+
     def test_fk_copy(self):
         c1 = Column('foo', Integer)
         c2 = Column('bar', Integer)
         m = MetaData()
         t1 = Table('t', m, c1, c2)
-        
+
         kw = dict(onupdate="X", 
                         ondelete="Y", use_alter=True, name='f1',
                         deferrable="Z", initially="Q", link_to_name=True)
-                        
+
         fk1 = ForeignKey(c1, **kw) 
         fk2 = ForeignKeyConstraint((c1,), (c2,), **kw)
-        
+
         t1.append_constraint(fk2)
         fk1c = fk1.copy()
         fk2c = fk2.copy()
-        
+
         for k in kw:
             eq_(getattr(fk1c, k), kw[k])
             eq_(getattr(fk2c, k), kw[k])
-    
+
     def test_fk_construct(self):
         c1 = Column('foo', Integer)
         c2 = Column('bar', Integer)
@@ -172,7 +172,7 @@ class MetaDataTest(TestBase, ComparesTables):
         t1 = Table('t', m, c1, c2)
         fk1 = ForeignKeyConstraint(('foo', ), ('bar', ), table=t1)
         assert fk1 in t1.constraints
-        
+
     @testing.exclude('mysql', '<', (4, 1, 1), 'early types are squirrely')
     def test_to_metadata(self):
         meta = MetaData()
@@ -264,7 +264,7 @@ class MetaDataTest(TestBase, ComparesTables):
                     assert not c.columns.contains_column(table.c.name)
         finally:
             meta.drop_all(testing.db)
-    
+
     def test_tometadata_with_schema(self):
         meta = MetaData()
 
@@ -314,7 +314,7 @@ class MetaDataTest(TestBase, ComparesTables):
             Column('data2', Integer),
         )
         Index('multi',table.c.data1,table.c.data2),
-        
+
         meta2 = MetaData()
         table_c = table.tometadata(meta2)
 
@@ -322,7 +322,7 @@ class MetaDataTest(TestBase, ComparesTables):
             return [i.name,i.unique] + \
                     sorted(i.kwargs.items()) + \
                     i.columns.keys()
-        
+
         eq_(
             sorted([_get_key(i) for i in table.indexes]),
             sorted([_get_key(i) for i in table_c.indexes])
@@ -330,7 +330,7 @@ class MetaDataTest(TestBase, ComparesTables):
 
     @emits_warning("Table '.+' already exists within the given MetaData")
     def test_tometadata_already_there(self):
-        
+
         meta1 = MetaData()
         table1 = Table('mytable', meta1,
             Column('myid', Integer, primary_key=True),
@@ -341,7 +341,7 @@ class MetaDataTest(TestBase, ComparesTables):
         )
 
         meta3 = MetaData()
-        
+
         table_c = table1.tometadata(meta2)
         table_d = table2.tometadata(meta2)
 
@@ -384,7 +384,7 @@ class MetaDataTest(TestBase, ComparesTables):
         c = Table('c', meta, Column('foo', Integer))
         d = Table('d', meta, Column('foo', Integer))
         e = Table('e', meta, Column('foo', Integer))
-        
+
         e.add_is_dependent_on(c)
         a.add_is_dependent_on(b)
         b.add_is_dependent_on(d)
@@ -394,7 +394,7 @@ class MetaDataTest(TestBase, ComparesTables):
             meta.sorted_tables,
             [d, b, a, c, e]
         )
-        
+
     def test_tometadata_strip_schema(self):
         meta = MetaData()
 
@@ -433,7 +433,7 @@ class TableTest(TestBase, AssertsCompiledSQL):
         table1 = Table("temporary_table_1", MetaData(),
                       Column("col1", Integer),
                       prefixes = ["TEMPORARY"])
-                      
+
         self.assert_compile(
             schema.CreateTable(table1), 
             "CREATE TEMPORARY TABLE temporary_table_1 (col1 INTEGER)"
@@ -480,8 +480,8 @@ class TableTest(TestBase, AssertsCompiledSQL):
             TypeError,
             assign
         )
-        
-        
+
+
 class ColumnDefinitionTest(TestBase):
     """Test Column() construction."""
 
@@ -570,4 +570,3 @@ class ColumnOptionsTest(TestBase):
             c.info['bar'] = 'zip'
             assert c.info['bar'] == 'zip'
 
-    
\ No newline at end of file
index 085845bc65fd1138db179f10229b0284d04982da..6a9055887dddb12dd255618beaffb369ab88f629 100644 (file)
@@ -23,7 +23,7 @@ class QueryTest(TestBase):
             Column('address', String(30)),
             test_needs_acid=True
             )
-            
+
         users2 = Table('u2', metadata,
             Column('user_id', INT, primary_key = True),
             Column('user_name', VARCHAR(20)),
@@ -47,7 +47,7 @@ class QueryTest(TestBase):
 
     def test_insert_heterogeneous_params(self):
         """test that executemany parameters are asserted to match the parameter set of the first."""
-        
+
         assert_raises_message(exc.InvalidRequestError, 
             "A value is required for bind parameter 'user_name', in parameter group 2",
             users.insert().execute,
@@ -87,10 +87,10 @@ class QueryTest(TestBase):
                 comp = ins.compile(engine, column_keys=list(values))
                 if not set(values).issuperset(c.key for c in table.primary_key):
                     assert comp.returning
-            
+
             result = engine.execute(table.insert(), **values)
             ret = values.copy()
-            
+
             for col, id in zip(table.primary_key, result.inserted_primary_key):
                 ret[col.key] = id
 
@@ -104,7 +104,7 @@ class QueryTest(TestBase):
 
         if testing.against('firebird', 'postgresql', 'oracle', 'mssql'):
             assert testing.db.dialect.implicit_returning
-            
+
         if testing.db.dialect.implicit_returning:
             test_engines = [
                 engines.testing_engine(options={'implicit_returning':False}),
@@ -112,7 +112,7 @@ class QueryTest(TestBase):
             ]
         else:
             test_engines = [testing.db]
-            
+
         for engine in test_engines:
             metadata = MetaData()
             for supported, table, values, assertvalues in [
@@ -208,14 +208,14 @@ class QueryTest(TestBase):
             ]
         else:
             test_engines = [testing.db]
-            
+
         for engine in test_engines:
-        
+
             r = engine.execute(users.insert(), 
                 {'user_name':'jack'},
             )
             assert r.closed
-    
+
     def test_row_iteration(self):
         users.insert().execute(
             {'user_id':7, 'user_name':'jack'},
@@ -245,25 +245,25 @@ class QueryTest(TestBase):
     @testing.fails_on('firebird', "kinterbasdb doesn't send full type information")
     def test_order_by_label(self):
         """test that a label within an ORDER BY works on each backend.
-        
+
         This test should be modified to support [ticket:1068] when that ticket
         is implemented.  For now, you need to put the actual string in the
         ORDER BY.
-        
+
         """
         users.insert().execute(
             {'user_id':7, 'user_name':'jack'},
             {'user_id':8, 'user_name':'ed'},
             {'user_id':9, 'user_name':'fred'},
         )
-        
+
         concat = ("test: " + users.c.user_name).label('thedata')
         print select([concat]).order_by("thedata")
         eq_(
             select([concat]).order_by("thedata").execute().fetchall(),
             [("test: ed",), ("test: fred",), ("test: jack",)]
         )
-        
+
         eq_(
             select([concat]).order_by("thedata").execute().fetchall(),
             [("test: ed",), ("test: fred",), ("test: jack",)]
@@ -285,8 +285,8 @@ class QueryTest(TestBase):
                 [("test: ed",), ("test: fred",), ("test: jack",)]
             )
         go()
-        
-        
+
+
     def test_row_comparison(self):
         users.insert().execute(user_id = 7, user_name = 'jack')
         rp = users.select().execute().first()
@@ -311,10 +311,10 @@ class QueryTest(TestBase):
         for pickle in False, True:
             for use_labels in False, True:
                 result = users.select(use_labels=use_labels).order_by(users.c.user_id).execute().fetchall()
-            
+
                 if pickle:
                     result = util.pickle.loads(util.pickle.dumps(result))
-                
+
                 eq_(
                     result, 
                     [(7, "jack"), (8, "ed"), (9, "fred")]
@@ -325,27 +325,27 @@ class QueryTest(TestBase):
                 else:
                     eq_(result[0]['user_id'], 7)
                     eq_(result[0].keys(), ["user_id", "user_name"])
-                    
+
                 eq_(result[0][0], 7)
                 eq_(result[0][users.c.user_id], 7)
                 eq_(result[0][users.c.user_name], 'jack')
-            
+
                 if use_labels:
                     assert_raises(exc.NoSuchColumnError, lambda: result[0][addresses.c.user_id])
                 else:
                     # test with a different table.  name resolution is 
                     # causing 'user_id' to match when use_labels wasn't used.
                     eq_(result[0][addresses.c.user_id], 7)
-            
+
                 assert_raises(exc.NoSuchColumnError, lambda: result[0]['fake key'])
                 assert_raises(exc.NoSuchColumnError, lambda: result[0][addresses.c.address_id])
-            
+
 
 
     @testing.requires.boolean_col_expressions
     def test_or_and_as_columns(self):
         true, false = literal(True), literal(False)
-        
+
         eq_(testing.db.execute(select([and_(true, false)])).scalar(), False)
         eq_(testing.db.execute(select([and_(true, true)])).scalar(), True)
         eq_(testing.db.execute(select([or_(true, false)])).scalar(), True)
@@ -359,7 +359,7 @@ class QueryTest(TestBase):
         row = testing.db.execute(select([or_(true, false).label("x"), and_(true, false).label("y")])).first()
         assert row.x == True
         assert row.y == False
-        
+
     def test_fetchmany(self):
         users.insert().execute(user_id = 7, user_name = 'jack')
         users.insert().execute(user_id = 8, user_name = 'ed')
@@ -394,7 +394,7 @@ class QueryTest(TestBase):
                     ), [(5,)]),
         ):
             eq_(expr.execute().fetchall(), result)
-    
+
     @testing.fails_on("firebird", "see dialect.test_firebird:MiscTest.test_percents_in_text")
     @testing.fails_on("oracle", "neither % nor %% are accepted")
     @testing.fails_on("informix", "neither % nor %% are accepted")
@@ -410,7 +410,7 @@ class QueryTest(TestBase):
             (text("select 'hello % world'"), "hello % world")
         ):
             eq_(testing.db.scalar(expr), result)
-        
+
     def test_ilike(self):
         users.insert().execute(
             {'user_id':1, 'user_name':'one'},
@@ -642,7 +642,7 @@ class QueryTest(TestBase):
         self.assert_(r[0:1] == (1,))
         self.assert_(r[1:] == (2, 'foo@bar.com'))
         self.assert_(r[:-1] == (1, 2))
-        
+
     def test_column_accessor(self):
         users.insert().execute(user_id=1, user_name='john')
         users.insert().execute(user_id=2, user_name='jack')
@@ -651,11 +651,11 @@ class QueryTest(TestBase):
         r = users.select(users.c.user_id==2).execute().first()
         self.assert_(r.user_id == r['user_id'] == r[users.c.user_id] == 2)
         self.assert_(r.user_name == r['user_name'] == r[users.c.user_name] == 'jack')
-        
+
         r = text("select * from query_users where user_id=2", bind=testing.db).execute().first()
         self.assert_(r.user_id == r['user_id'] == r[users.c.user_id] == 2)
         self.assert_(r.user_name == r['user_name'] == r[users.c.user_name] == 'jack')
-        
+
         # test a little sqlite weirdness - with the UNION, 
         # cols come back as "query_users.user_id" in cursor.description
         r = text("select query_users.user_id, query_users.user_name from query_users "
@@ -682,14 +682,14 @@ class QueryTest(TestBase):
             users.insert(),
             {'user_id':1, 'user_name':'ed'}
         )
-        
+
         eq_(r.lastrowid, 1)
-        
-        
+
+
     def test_graceful_fetch_on_non_rows(self):
         """test that calling fetchone() etc. on a result that doesn't
         return rows fails gracefully.
-        
+
         """
 
         # these proxies don't work with no cursor.description present.
@@ -709,7 +709,7 @@ class QueryTest(TestBase):
                 getattr(result, meth),
             )
             trans.rollback()
-    
+
     def test_no_inserted_pk_on_non_insert(self):
         result = testing.db.execute("select * from query_users")
         assert_raises_message(
@@ -717,7 +717,7 @@ class QueryTest(TestBase):
             r"Statement is not an insert\(\) expression construct.",
             getattr, result, 'inserted_primary_key'
         )
-    
+
     @testing.requires.returning
     def test_no_inserted_pk_on_returning(self):
         result = testing.db.execute(users.insert().returning(users.c.user_id, users.c.user_name))
@@ -726,7 +726,7 @@ class QueryTest(TestBase):
             r"Can't call inserted_primary_key when returning\(\) is used.",
             getattr, result, 'inserted_primary_key'
         )
-        
+
     def test_fetchone_til_end(self):
         result = testing.db.execute("select * from query_users")
         eq_(result.fetchone(), None)
@@ -738,17 +738,17 @@ class QueryTest(TestBase):
 
     def test_result_case_sensitivity(self):
         """test name normalization for result sets."""
-        
+
         row = testing.db.execute(
             select([
                 literal_column("1").label("case_insensitive"),
                 literal_column("2").label("CaseSensitive")
             ])
         ).first()
-        
+
         assert row.keys() == ["case_insensitive", "CaseSensitive"]
 
-        
+
     def test_row_as_args(self):
         users.insert().execute(user_id=1, user_name='john')
         r = users.select(users.c.user_id==1).execute().first()
@@ -761,12 +761,12 @@ class QueryTest(TestBase):
         r = users.select().execute()
         users2.insert().execute(list(r))
         assert users2.select().execute().fetchall() == [(1, 'john'), (2, 'ed')]
-        
+
         users2.delete().execute()
         r = users.select().execute()
         users2.insert().execute(*list(r))
         assert users2.select().execute().fetchall() == [(1, 'john'), (2, 'ed')]
-        
+
     def test_ambiguous_column(self):
         users.insert().execute(user_id=1, user_name='john')
         r = users.outerjoin(addresses).select().execute().first()
@@ -782,7 +782,7 @@ class QueryTest(TestBase):
             "Ambiguous column name",
             lambda: r['user_id']
         )
-        
+
         result = users.outerjoin(addresses).select().execute()
         result = base.BufferedColumnResultProxy(result.context)
         r = result.first()
@@ -821,7 +821,7 @@ class QueryTest(TestBase):
         users.insert().execute(user_id=1, user_name='foo')
         r = users.select().execute().first()
         eq_(len(r), 2)
-            
+
         r = testing.db.execute('select user_name, user_id from query_users').first()
         eq_(len(r), 2)
         r = testing.db.execute('select user_name from query_users').first()
@@ -924,10 +924,10 @@ class QueryTest(TestBase):
                          "uses sql-92 rules")
     def test_bind_in(self):
         """test calling IN against a bind parameter.
-        
+
         this isn't allowed on several platforms since we
         generate ? = ?.
-        
+
         """
         users.insert().execute(user_id = 7, user_name = 'jack')
         users.insert().execute(user_id = 8, user_name = 'fred')
@@ -940,7 +940,7 @@ class QueryTest(TestBase):
         assert len(r) == 3
         r = s.execute(search_key=None).fetchall()
         assert len(r) == 0
-    
+
     @testing.emits_warning('.*empty sequence.*')
     @testing.fails_on('firebird', 'uses sql-92 bind rules')
     def test_literal_in(self):
@@ -953,15 +953,15 @@ class QueryTest(TestBase):
         s = users.select(not_(literal("john").in_([])))
         r = s.execute().fetchall()
         assert len(r) == 3
-        
-        
+
+
     @testing.emits_warning('.*empty sequence.*')
     @testing.requires.boolean_col_expressions
     def test_in_filtering_advanced(self):
         """test the behavior of the in_() function when 
         comparing against an empty collection, specifically
         that a proper boolean value is generated.
-        
+
         """
 
         users.insert().execute(user_id = 7, user_name = 'jack')
@@ -980,11 +980,11 @@ class QueryTest(TestBase):
 
 class PercentSchemaNamesTest(TestBase):
     """tests using percent signs, spaces in table and column names.
-    
+
     Doesn't pass for mysql, postgresql, but this is really a 
     SQLAlchemy bug - we should be escaping out %% signs for this
     operation the same way we do for text() and column labels.
-    
+
     """
 
     @classmethod
@@ -999,11 +999,11 @@ class PercentSchemaNamesTest(TestBase):
 
     def teardown(self):
         percent_table.delete().execute()
-        
+
     @classmethod
     def teardown_class(cls):
         metadata.drop_all()
-    
+
     def test_single_roundtrip(self):
         percent_table.insert().execute(
             {'percent%':5, 'spaces % more spaces':12},
@@ -1018,7 +1018,7 @@ class PercentSchemaNamesTest(TestBase):
             {'percent%':11, 'spaces % more spaces':9},
         )
         self._assert_table()
-    
+
     @testing.crashes('mysql+mysqldb', 'MySQLdb handles executemany() inconsistently vs. execute()')
     def test_executemany_roundtrip(self):
         percent_table.insert().execute(
@@ -1030,7 +1030,7 @@ class PercentSchemaNamesTest(TestBase):
             {'percent%':11, 'spaces % more spaces':9},
         )
         self._assert_table()
-        
+
     def _assert_table(self):
         for table in (percent_table, percent_table.alias()):
             eq_(
@@ -1073,9 +1073,9 @@ class PercentSchemaNamesTest(TestBase):
                 (11, 15)
             ]
         )
-        
-        
-        
+
+
+
 class LimitTest(TestBase):
 
     @classmethod
@@ -1106,7 +1106,7 @@ class LimitTest(TestBase):
         addresses.insert().execute(address_id=6, user_id=6, address='addr5')
         users.insert().execute(user_id=7, user_name='fido')
         addresses.insert().execute(address_id=7, user_id=7, address='addr5')
-        
+
     @classmethod
     def teardown_class(cls):
         metadata.drop_all()
@@ -1189,11 +1189,11 @@ class CompoundTest(TestBase):
             dict(col2="t3col2r2", col3="bbb", col4="aaa"),
             dict(col2="t3col2r3", col3="ccc", col4="bbb"),
         ])
-        
+
     @engines.close_first
     def teardown(self):
         pass
-        
+
     @classmethod
     def teardown_class(cls):
         metadata.drop_all()
@@ -1274,13 +1274,13 @@ class CompoundTest(TestBase):
         """like test_union_all, but breaks the sub-union into 
         a subquery with an explicit column reference on the outside,
         more palatable to a wider variety of engines.
-        
+
         """
         u = union(
             select([t1.c.col3]),
             select([t1.c.col3]),
         ).alias()
-        
+
         e = union_all(
             select([t1.c.col3]),
             select([u.c.col3])
@@ -1327,7 +1327,7 @@ class CompoundTest(TestBase):
     def test_except_style2(self):
         # same as style1, but add alias().select() to the except_().
         # sqlite can handle it now.
-        
+
         e = except_(union(
             select([t1.c.col3, t1.c.col4]),
             select([t2.c.col3, t2.c.col4]),
@@ -1368,7 +1368,7 @@ class CompoundTest(TestBase):
                 select([t3.c.col3], t3.c.col3 == 'ccc'), #ccc
             ).alias().select()
         )
-        
+
         eq_(e.execute().fetchall(), [('ccc',)])
         eq_(
             e.alias().select().execute().fetchall(),
@@ -1409,7 +1409,7 @@ class CompoundTest(TestBase):
         found = self._fetchall_sorted(u.execute())
 
         eq_(found, wanted)
-    
+
     @testing.requires.intersect
     def test_intersect_unions_3(self):
         u = intersect(
@@ -1733,7 +1733,7 @@ class OperatorTest(TestBase):
     @classmethod
     def teardown_class(cls):
         metadata.drop_all()
-    
+
 
     # TODO: seems like more tests warranted for this setup.
     def test_modulo(self):
index e880388d7ee01ff77f8a78ddd0f52764d9e22d73..2aa5086c6200db6fb5e147993e496bb6b8152689 100644 (file)
@@ -96,7 +96,7 @@ class QuoteTest(TestBase, AssertsCompiledSQL):
             '''SELECT 1 FROM (SELECT "foo"."t1"."col1" AS "col1" FROM '''\
             '''"foo"."t1") AS anon WHERE anon."col1" = :col1_1'''
         )
-        
+
         metadata = MetaData()
         t1 = Table('TableOne', metadata,
             Column('ColumnOne', Integer, quote=False), quote=False, schema="FooBar", quote_schema=False)
@@ -105,7 +105,7 @@ class QuoteTest(TestBase, AssertsCompiledSQL):
         self.assert_compile(t1.select().apply_labels(), 
             "SELECT FooBar.TableOne.ColumnOne AS "\
             "FooBar_TableOne_ColumnOne FROM FooBar.TableOne"   # TODO: is this what we really want here ?  what if table/schema 
-                                                               # *are* quoted?  
+                                                               # *are* quoted?
         )
 
         a = t1.select().alias('anon')
index 632a739f1d10f4f6f193fe0fd0f426b26ec0ff4f..2a8e6fc2f0cbcfde43d26e9cac5e34136775c241 100644 (file)
@@ -10,10 +10,10 @@ class ReturningTest(TestBase, AssertsExecutionResults):
     def setup(self):
         meta = MetaData(testing.db)
         global table, GoofyType
-        
+
         class GoofyType(TypeDecorator):
             impl = String
-            
+
             def process_bind_param(self, value, dialect):
                 if value is None:
                     return None
@@ -23,7 +23,7 @@ class ReturningTest(TestBase, AssertsExecutionResults):
                 if value is None:
                     return None
                 return value + "BAR"
-            
+
         table = Table('tables', meta,
             Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
             Column('persons', Integer),
@@ -31,19 +31,19 @@ class ReturningTest(TestBase, AssertsExecutionResults):
             Column('goofy', GoofyType(50))
         )
         table.create(checkfirst=True)
-    
+
     def teardown(self):
         table.drop()
-    
+
     @testing.exclude('firebird', '<', (2, 0), '2.0+ feature')
     @testing.exclude('postgresql', '<', (8, 2), '8.2+ feature')
     def test_column_targeting(self):
         result = table.insert().returning(table.c.id, table.c.full).execute({'persons': 1, 'full': False})
-        
+
         row = result.first()
         assert row[table.c.id] == row['id'] == 1
         assert row[table.c.full] == row['full'] == False
-        
+
         result = table.insert().values(persons=5, full=True, goofy="somegoofy").\
                             returning(table.c.persons, table.c.full, table.c.goofy).execute()
         row = result.first()
@@ -52,7 +52,7 @@ class ReturningTest(TestBase, AssertsExecutionResults):
 
         eq_(row[table.c.goofy], row['goofy'])
         eq_(row['goofy'], "FOOsomegoofyBAR")
-    
+
     @testing.fails_on('firebird', "fb can't handle returning x AS y")
     @testing.exclude('firebird', '<', (2, 0), '2.0+ feature')
     @testing.exclude('postgresql', '<', (8, 2), '8.2+ feature')
@@ -76,7 +76,7 @@ class ReturningTest(TestBase, AssertsExecutionResults):
                             returning(table.c.persons + 18).execute()
         row = result.first()
         assert row[0] == 30
-        
+
     @testing.exclude('firebird', '<', (2, 1), '2.1+ feature')
     @testing.exclude('postgresql', '<', (8, 2), '8.2+ feature')
     def test_update_returning(self):
@@ -115,8 +115,8 @@ class ReturningTest(TestBase, AssertsExecutionResults):
 
         test_executemany()
 
-    
-        
+
+
     @testing.exclude('firebird', '<', (2, 1), '2.1+ feature')
     @testing.exclude('postgresql', '<', (8, 2), '8.2+ feature')
     @testing.fails_on_everything_except('postgresql', 'firebird')
@@ -164,7 +164,7 @@ class SequenceReturningTest(TestBase):
 
 class KeyReturningTest(TestBase, AssertsExecutionResults):
     """test returning() works with columns that define 'key'."""
-    
+
     __unsupported_on__ = ('sqlite', 'mysql', 'maxdb', 'sybase', 'access')
 
     def setup(self):
@@ -186,8 +186,8 @@ class KeyReturningTest(TestBase, AssertsExecutionResults):
         result = table.insert().returning(table.c.foo_id).execute(data='somedata')
         row = result.first()
         assert row[table.c.foo_id] == row['id'] == 1
-        
+
         result = table.select().execute().first()
         assert row[table.c.foo_id] == row['id'] == 1
-        
+
 
index ed40f28018877a3e6786399b3376733d401691c8..fc74e8467557011fa16bc1cb8f41245502d57cfd 100644 (file)
@@ -4,9 +4,9 @@ from test.lib import *
 
 class FoundRowsTest(TestBase, AssertsExecutionResults):
     """tests rowcount functionality"""
-    
+
     __requires__ = ('sane_rowcount', )
-    
+
     @classmethod
     def setup_class(cls):
         global employees_table, metadata
index 77acf896b6d8da2ebeea3688ebd66758835f30ca..243c56dcf701be9fd7d5aeb56d4a60265f632965 100644 (file)
@@ -31,7 +31,7 @@ class SelectableTest(TestBase, AssertsExecutionResults):
     def test_indirect_correspondence_on_labels(self):
         # this test depends upon 'distance' to
         # get the right result
-        
+
         # same column three times
 
         s = select([table1.c.col1.label('c2'), table1.c.col1,
@@ -48,7 +48,7 @@ class SelectableTest(TestBase, AssertsExecutionResults):
     def test_direct_correspondence_on_labels(self):
         # this test depends on labels being part
         # of the proxy set to get the right result
-        
+
         l1, l2 = table1.c.col1.label('foo'), table1.c.col1.label('bar')
         sel = select([l1, l2])
 
@@ -85,20 +85,20 @@ class SelectableTest(TestBase, AssertsExecutionResults):
         j2 = jjj.alias('foo')
         assert j2.corresponding_column(table1.c.col1) \
             is j2.c.table1_col1
-    
+
     def test_against_cloned_non_table(self):
         # test that corresponding column digs across
         # clone boundaries with anonymous labeled elements
         col = func.count().label('foo')
         sel = select([col])
-        
+
         sel2 = visitors.ReplacingCloningVisitor().traverse(sel)
         assert sel2.corresponding_column(col) is sel2.c.foo
 
         sel3 = visitors.ReplacingCloningVisitor().traverse(sel2)
         assert sel3.corresponding_column(col) is sel3.c.foo
 
-        
+
     def test_select_on_table(self):
         sel = select([table1, table2], use_labels=True)
 
@@ -153,22 +153,22 @@ class SelectableTest(TestBase, AssertsExecutionResults):
     def test_union_precedence(self):
         # conflicting column correspondence should be resolved based on 
         # the order of the select()s in the union
-        
+
         s1 = select([table1.c.col1, table1.c.col2])
         s2 = select([table1.c.col2, table1.c.col1])
         s3 = select([table1.c.col3, table1.c.colx])
         s4 = select([table1.c.colx, table1.c.col3])
-        
+
         u1 = union(s1, s2)
         assert u1.corresponding_column(table1.c.col1) is u1.c.col1
         assert u1.corresponding_column(table1.c.col2) is u1.c.col2
-        
+
         u1 = union(s1, s2, s3, s4)
         assert u1.corresponding_column(table1.c.col1) is u1.c.col1
         assert u1.corresponding_column(table1.c.col2) is u1.c.col2
         assert u1.corresponding_column(table1.c.colx) is u1.c.col2
         assert u1.corresponding_column(table1.c.col3) is u1.c.col1
-        
+
 
     def test_singular_union(self):
         u = union(select([table1.c.col1, table1.c.col2,
@@ -254,13 +254,13 @@ class SelectableTest(TestBase, AssertsExecutionResults):
         j = join(a, table2)
         criterion = a.c.acol1 == table2.c.col2
         self.assert_(criterion.compare(j.onclause))
-    
+
     def test_labeled_select_correspoinding(self):
         l1 = select([func.max(table1.c.col1)]).label('foo')
 
         s = select([l1])
         eq_(s.corresponding_column(l1), s.c.foo)
-        
+
         s = select([table1.c.col1, l1])
         eq_(s.corresponding_column(l1), s.c.foo)
 
@@ -300,7 +300,7 @@ class SelectableTest(TestBase, AssertsExecutionResults):
         s = select([t2, t3], use_labels=True)
 
         assert_raises(exc.NoReferencedTableError, s.join, t1)
-    
+
 
     def test_join_condition(self):
         m = MetaData()
@@ -326,7 +326,7 @@ class SelectableTest(TestBase, AssertsExecutionResults):
             ]:
             assert expected.compare(sql_util.join_condition(left,
                                     right, a_subset=a_subset))
-        
+
         # these are ambiguous, or have no joins
         for left, right, a_subset in [
             (t1t2, t3, None),
@@ -339,7 +339,7 @@ class SelectableTest(TestBase, AssertsExecutionResults):
                 sql_util.join_condition,
                 left, right, a_subset=a_subset
             )
-        
+
         als = t2t3.alias()
         # test join's behavior, including natural
         for left, right, expected in [
@@ -370,7 +370,7 @@ class SelectableTest(TestBase, AssertsExecutionResults):
                               "Perhaps you meant to convert the right "
                               "side to a subquery using alias\(\)\?",
                               t1t2.join, t2t3.select(use_labels=True))
-        
+
 
 class PrimaryKeyTest(TestBase, AssertsExecutionResults):
 
@@ -488,7 +488,7 @@ class ReduceTest(TestBase, AssertsExecutionResults):
         t3 = Table('t3', meta,
             Column('t3id', Integer, ForeignKey('t2.t2id'), primary_key=True),
             Column('t3data', String(30)))
-        
+
         eq_(util.column_set(sql_util.reduce_columns([
             t1.c.t1id,
             t1.c.t1data,
@@ -498,7 +498,7 @@ class ReduceTest(TestBase, AssertsExecutionResults):
             t3.c.t3data,
             ])), util.column_set([t1.c.t1id, t1.c.t1data, t2.c.t2data,
                                  t3.c.t3data]))
-    
+
 
     def test_reduce_selectable(self):
         metadata = MetaData()
@@ -514,7 +514,7 @@ class ReduceTest(TestBase, AssertsExecutionResults):
         eq_(util.column_set(sql_util.reduce_columns(list(s.c), s)),
             util.column_set([s.c.engineer_id, s.c.engineer_name,
             s.c.manager_id]))
-       
+
 
     def test_reduce_aliased_join(self):
         metadata = MetaData()
@@ -543,7 +543,7 @@ class ReduceTest(TestBase, AssertsExecutionResults):
         eq_(util.column_set(sql_util.reduce_columns([pjoin.c.people_person_id,
             pjoin.c.engineers_person_id, pjoin.c.managers_person_id])),
             util.column_set([pjoin.c.people_person_id]))
-        
+
     def test_reduce_aliased_union(self):
         metadata = MetaData()
 
@@ -567,7 +567,7 @@ class ReduceTest(TestBase, AssertsExecutionResults):
             item_join.c.dummy, item_join.c.child_name])),
             util.column_set([item_join.c.id, item_join.c.dummy,
             item_join.c.child_name]))
-    
+
 
     def test_reduce_aliased_union_2(self):
         metadata = MetaData()
@@ -597,7 +597,7 @@ class ReduceTest(TestBase, AssertsExecutionResults):
                      select_from(
                         page_table.join(magazine_page_table).
                         join(classified_page_table)),
-                        
+
                     select([
                         page_table.c.id,
                         magazine_page_table.c.page_id, 
@@ -622,7 +622,7 @@ class ReduceTest(TestBase, AssertsExecutionResults):
                         cast(null(), Integer).label('magazine_page_id')
                       ]).
                       select_from(page_table.join(magazine_page_table)),
-                      
+
                       select([
                         page_table.c.id,
                         magazine_page_table.c.page_id,
@@ -684,7 +684,7 @@ class AnnotationsTest(TestBase):
             def __init__(self):
                 Column.__init__(self, 'foo', Integer)
             _constructor = Column
-            
+
         t1 = Table('t1', MetaData(), MyColumn())
         s1 = t1.select()
         assert isinstance(t1.c.foo, MyColumn)
@@ -695,14 +695,14 @@ class AnnotationsTest(TestBase):
         assert isinstance(s2.c.foo, Column)
         annot_2 = s1._annotate({})
         assert isinstance(annot_2.c.foo, Column)
-        
+
     def test_annotated_corresponding_column(self):
         table1 = table('table1', column("col1"))
-        
+
         s1 = select([table1.c.col1])
         t1 = s1._annotate({})
         t2 = s1
-        
+
         # t1 needs to share the same _make_proxy() columns as t2, even
         # though it's annotated.  otherwise paths will diverge once they
         # are corresponded against "inner" below.
@@ -723,12 +723,12 @@ class AnnotationsTest(TestBase):
 
     def test_annotated_visit(self):
         table1 = table('table1', column("col1"), column("col2"))
-        
+
         bin = table1.c.col1 == bindparam('foo', value=None)
         assert str(bin) == "table1.col1 = :foo"
         def visit_binary(b):
             b.right = table1.c.col2
-            
+
         b2 = visitors.cloned_traverse(bin, {}, {'binary':visit_binary})
         assert str(b2) == "table1.col1 = table1.col2"
 
@@ -739,13 +739,13 @@ class AnnotationsTest(TestBase):
 
         def visit_binary(b):
             b.left = bindparam('bar')
-        
+
         b4 = visitors.cloned_traverse(b2, {}, {'binary':visit_binary})
         assert str(b4) == ":bar = table1.col2"
 
         b5 = visitors.cloned_traverse(b3, {}, {'binary':visit_binary})
         assert str(b5) == ":bar = table1.col2"
-    
+
 
     def test_annotate_expressions(self):
         table1 = table('table1', column('col1'), column('col2'))
@@ -760,10 +760,10 @@ class AnnotationsTest(TestBase):
             eq_(str(sql_util._deep_annotate(expr, {})), expected)
             eq_(str(sql_util._deep_annotate(expr, {},
                 exclude=[table1.c.col1])), expected)
-        
+
     def test_deannotate(self):
         table1 = table('table1', column("col1"), column("col2"))
-        
+
         bin = table1.c.col1 == bindparam('foo', value=None)
 
         b2 = sql_util._deep_annotate(bin, {'_orm_adapt':True})
@@ -772,7 +772,7 @@ class AnnotationsTest(TestBase):
 
         for elem in (b2._annotations, b2.left._annotations):
             assert '_orm_adapt' in elem
-        
+
         for elem in b3._annotations, b3.left._annotations, \
             b4._annotations, b4.left._annotations:
             assert elem == {}
@@ -781,4 +781,4 @@ class AnnotationsTest(TestBase):
         assert b3.left is not b2.left is not bin.left
         assert b4.left is bin.left  # since column is immutable
         assert b4.right is not bin.right is not b2.right is not b3.right
-        
+
index 700f7b7de8d5303c0680d9e4c4ee8883fe9299e9..1665e35c88b168ff44095e7907e01bd2c8941f33 100644 (file)
@@ -22,11 +22,11 @@ class AdaptTest(TestBase):
             for d in dialects.__all__
             if not d.startswith('_')
         ]
-        
+
     def _all_dialects(self):
         return [d.base.dialect() for d in 
                 self._all_dialect_modules()]
-    
+
     def _all_types(self):
         def types_for_mod(mod):
             for key in dir(mod):
@@ -34,24 +34,24 @@ class AdaptTest(TestBase):
                 if not isinstance(typ, type) or not issubclass(typ, types.TypeEngine):
                     continue
                 yield typ
-        
+
         for typ in types_for_mod(types):
             yield typ
         for dialect in self._all_dialect_modules():
             for typ in types_for_mod(dialect):
                 yield typ
-        
+
     def test_uppercase_rendering(self):
         """Test that uppercase types from types.py always render as their
         type.
-        
+
         As of SQLA 0.6, using an uppercase type means you want specifically
         that type. If the database in use doesn't support that DDL, it (the DB
         backend) should raise an error - it means you should be using a
         lowercased (genericized) type.
-        
+
         """
-        
+
         for dialect in self._all_dialects():
             for type_, expected in (
                 (FLOAT, "FLOAT"),
@@ -77,29 +77,29 @@ class AdaptTest(TestBase):
 
                 compiled = types.to_instance(type_).\
                             compile(dialect=dialect)
-                    
+
                 assert compiled in expected, \
                     "%r matches none of %r for dialect %s" % \
                     (compiled, expected, dialect.name)
-                
+
                 assert str(types.to_instance(type_)) in expected, \
                     "default str() of type %r not expected, %r" % \
                     (type_, expected)
-    
+
     @testing.uses_deprecated()
     def test_adapt_method(self):
         """ensure all types have a working adapt() method,
-        which creates a distinct copy.   
-        
+        which creates a distinct copy.
+
         The distinct copy ensures that when we cache
         the adapted() form of a type against the original
         in a weak key dictionary, a cycle is not formed.
-        
+
         This test doesn't test type-specific arguments of
         adapt() beyond their defaults.
-        
+
         """
-        
+
         for typ in self._all_types():
             if typ in (types.TypeDecorator, types.TypeEngine):
                 continue
@@ -117,8 +117,8 @@ class AdaptTest(TestBase):
                     if k == 'impl':
                         continue
                     eq_(getattr(t2, k), t1.__dict__[k])
-        
-        
+
+
 class TypeAffinityTest(TestBase):
     def test_type_affinity(self):
         for type_, affin in [
@@ -128,7 +128,7 @@ class TypeAffinityTest(TestBase):
             (LargeBinary(), types._Binary)
         ]:
             eq_(type_._type_affinity, affin)
-            
+
         for t1, t2, comp in [
             (Integer(), SmallInteger(), True),
             (Integer(), String(), False),
@@ -169,7 +169,7 @@ class PickleMetadataTest(TestBase):
                 Table('foo', meta, column_type)
                 ct = loads(dumps(column_type))
                 mt = loads(dumps(meta))
-                
+
 
 class UserDefinedTest(TestBase, AssertsCompiledSQL):
     """tests user-defined types."""
@@ -210,37 +210,37 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
         ]:
             for dialect_ in (dialects.postgresql, dialects.mssql, dialects.mysql):
                 dialect_ = dialect_.dialect()
-                
+
                 raw_impl = types.to_instance(impl_, **kw)
-                
+
                 class MyType(types.TypeDecorator):
                     impl = impl_
-                
+
                 dec_type = MyType(**kw)
-                
+
                 eq_(dec_type.impl.__class__, raw_impl.__class__)
-                
+
                 raw_dialect_impl = raw_impl.dialect_impl(dialect_)
                 dec_dialect_impl = dec_type.dialect_impl(dialect_)
                 eq_(dec_dialect_impl.__class__, MyType)
                 eq_(raw_dialect_impl.__class__ , dec_dialect_impl.impl.__class__)
-                
+
                 self.assert_compile(
                     MyType(**kw),
                     exp,
                     dialect=dialect_
                 )
-    
+
     def test_user_defined_typedec_impl(self):
         class MyType(types.TypeDecorator):
             impl = Float
-            
+
             def load_dialect_impl(self, dialect):
                 if dialect.name == 'sqlite':
                     return String(50)
                 else:
                     return super(MyType, self).load_dialect_impl(dialect)
-        
+
         sl = dialects.sqlite.dialect()
         pg = dialects.postgresql.dialect()
         t = MyType()
@@ -254,35 +254,35 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
                 t.dialect_impl(dialect=pg).impl.__class__, 
                 Float().dialect_impl(pg).__class__
         )
-    
+
     @testing.provide_metadata
     def test_type_coerce(self):
         """test ad-hoc usage of custom types with type_coerce()."""
-        
+
         class MyType(types.TypeDecorator):
             impl = String
 
             def process_bind_param(self, value, dialect):
                 return value[0:-8]
-            
+
             def process_result_value(self, value, dialect):
                 return value + "BIND_OUT"
-        
+
         t = Table('t', metadata, Column('data', String(50)))
         metadata.create_all()
-        
+
         t.insert().values(data=type_coerce('d1BIND_OUT',MyType)).execute()
 
         eq_(
             select([type_coerce(t.c.data, MyType)]).execute().fetchall(),
             [('d1BIND_OUT', )]
         )
-        
+
         eq_(
             select([t.c.data, type_coerce(t.c.data, MyType)]).execute().fetchall(),
             [('d1', 'd1BIND_OUT')]
         )
-        
+
         eq_(
             select([t.c.data, type_coerce(t.c.data, MyType)]).\
                         where(type_coerce(t.c.data, MyType) == 'd1BIND_OUT').\
@@ -310,7 +310,7 @@ class UserDefinedTest(TestBase, AssertsCompiledSQL):
                         execute().fetchall(),
             []
         )
-        
+
     @classmethod
     def setup_class(cls):
         global users, metadata
@@ -432,7 +432,7 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
             Column('unicode_text', UnicodeText),
             )
         metadata.create_all()
-        
+
     @classmethod
     def teardown_class(cls):
         metadata.drop_all()
@@ -440,26 +440,26 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
     @engines.close_first
     def teardown(self):
         unicode_table.delete().execute()
-    
+
     def test_native_unicode(self):
         """assert expected values for 'native unicode' mode"""
-       
+
         if \
             (testing.against('mssql+pyodbc') and not testing.db.dialect.freetds):
             assert testing.db.dialect.returns_unicode_strings == 'conditional'
             return
-        
+
         if testing.against('mssql+pymssql'):
             assert testing.db.dialect.returns_unicode_strings == ('charset' in testing.db.url.query)
             return
-            
+
         assert testing.db.dialect.returns_unicode_strings == \
             ((testing.db.name, testing.db.driver) in \
             (
                 ('postgresql','psycopg2'),
                 ('postgresql','pypostgresql'),
                 ('postgresql','pg8000'),
-                ('postgresql','zxjdbc'),  
+                ('postgresql','zxjdbc'),
                 ('mysql','oursql'),
                 ('mysql','zxjdbc'),
                 ('mysql','mysqlconnector'),
@@ -471,14 +471,14 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
                                         (testing.db.name, 
                                          testing.db.driver, 
                                          testing.db.dialect.returns_unicode_strings)
-        
+
     def test_round_trip(self):
         unicodedata = u"Alors vous imaginez ma surprise, au lever du jour, "\
                     u"quand une drôle de petit voix m’a réveillé. Elle "\
                     u"disait: Â« S’il vous plaît… dessine-moi un mouton! Â»"
-        
+
         unicode_table.insert().execute(unicode_varchar=unicodedata,unicode_text=unicodedata)
-        
+
         x = unicode_table.select().execute().first()
         assert isinstance(x['unicode_varchar'], unicode)
         assert isinstance(x['unicode_text'], unicode)
@@ -488,7 +488,7 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
     def test_round_trip_executemany(self):
         # cx_oracle was producing different behavior for cursor.executemany()
         # vs. cursor.execute()
-        
+
         unicodedata = u"Alors vous imaginez ma surprise, au lever du jour, quand "\
                         u"une drôle de petit voix m’a réveillé. "\
                         u"Elle disait: Â« S’il vous plaît… dessine-moi un mouton! Â»"
@@ -512,12 +512,12 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
                         u"Elle disait: Â« S’il vous plaît… dessine-moi un mouton! Â»"
 
         unicode_table.insert().execute(unicode_varchar=unicodedata,unicode_text=unicodedata)
-                                       
+
         x = union(
                     select([unicode_table.c.unicode_varchar]),
                     select([unicode_table.c.unicode_varchar])
                 ).execute().first()
-        
+
         assert isinstance(x['unicode_varchar'], unicode)
         eq_(x['unicode_varchar'], unicodedata)
 
@@ -529,13 +529,13 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
     def test_unicode_warnings(self):
         """test the warnings raised when SQLA must coerce unicode binds,
         *and* is using the Unicode type.
-        
+
         """
 
         unicodedata = u"Alors vous imaginez ma surprise, au lever du jour, quand "\
                         u"une drôle de petit voix m’a réveillé. "\
                         u"Elle disait: Â« S’il vous plaît… dessine-moi un mouton! Â»"
-        
+
         # using Unicode explicly - warning should be emitted
         u = Unicode()
         uni = u.dialect_impl(testing.db.dialect).bind_processor(testing.db.dialect)
@@ -557,14 +557,14 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
             assert_raises(exc.SAWarning, uni, 'x')
             assert isinstance(uni(unicodedata), str)
             # end Py2K
-        
+
             eq_(uni(unicodedata), unicodedata.encode('utf-8'))
-        
+
         # using convert unicode at engine level - 
         # this should not be raising a warning
         unicode_engine = engines.utf8_engine(options={'convert_unicode':True,})
         unicode_engine.dialect.supports_unicode_binds = False
-        
+
         s = String()
         uni = s.dialect_impl(unicode_engine.dialect).bind_processor(unicode_engine.dialect)
         # this is not the unicode type - no warning
@@ -575,36 +575,36 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
         uni('x')
         assert isinstance(uni(unicodedata), str)
         # end Py2K
-        
+
         eq_(uni(unicodedata), unicodedata.encode('utf-8'))
-    
+
     @testing.fails_if(
                         lambda: testing.db_spec("postgresql+pg8000")(testing.db) and util.py3k,
                         "pg8000 appropriately does not accept 'bytes' for a VARCHAR column."
                         )
     def test_ignoring_unicode_error(self):
         """checks String(unicode_error='ignore') is passed to underlying codec."""
-        
+
         unicodedata = u"Alors vous imaginez ma surprise, au lever du jour, quand "\
                         u"une drôle de petit voix m’a réveillé. "\
                         u"Elle disait: Â« S’il vous plaît… dessine-moi un mouton! Â»"
-        
+
         asciidata = unicodedata.encode('ascii', 'ignore')
-        
+
         m = MetaData()
         table = Table('unicode_err_table', m,
             Column('sort', Integer),
             Column('plain_varchar_no_coding_error', \
                     String(248, convert_unicode='force', unicode_error='ignore'))
             )
-        
+
         m2 = MetaData()
         utf8_table = Table('unicode_err_table', m2,
             Column('sort', Integer),
             Column('plain_varchar_no_coding_error', \
                     String(248, convert_unicode=True))
             )
-        
+
         engine = engines.testing_engine(options={'encoding':'ascii'})
         m.create_all(engine)
         try:
@@ -619,7 +619,7 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
             # switch to utf-8
             engine.dialect.encoding = 'utf-8'
             from binascii import hexlify
-            
+
             # the row that we put in was stored as hexlified ascii
             row = engine.execute(utf8_table.select()).first()
             x = row['plain_varchar_no_coding_error']
@@ -629,7 +629,7 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
             a = hexlify(x)
             b = hexlify(asciidata)
             eq_(a, b)
-            
+
             # insert another row which will be stored with
             # utf-8 only chars
             engine.execute(
@@ -649,7 +649,7 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
             ascii_row = result.fetchone()
             utf8_row = result.fetchone()
             result.close()
-            
+
             x = ascii_row['plain_varchar_no_coding_error']
             # on python3 "x" comes back as string (i.e. unicode),
             # hexlify requires bytes
@@ -671,7 +671,7 @@ class UnicodeTest(TestBase, AssertsExecutionResults):
             else:
                 a = hexlify(x)
                 eq_(a, b)
-                
+
         finally:
             m.drop_all(engine)
 
@@ -692,11 +692,11 @@ class EnumTest(TestBase):
         )
 
         metadata.create_all()
-    
+
     def teardown(self):
         enum_table.delete().execute()
         non_native_enum_table.delete().execute()
-        
+
     @classmethod
     def teardown_class(cls):
         metadata.drop_all()
@@ -713,7 +713,7 @@ class EnumTest(TestBase):
             {'id':2, 'someenum':'two'},
             {'id':3, 'someenum':'one'},
         ])
-        
+
         eq_(
             enum_table.select().order_by(enum_table.c.id).execute().fetchall(), 
             [
@@ -739,7 +739,7 @@ class EnumTest(TestBase):
                 (3, 'one'),
             ]
         )
-    
+
     def test_adapt(self):
         from sqlalchemy.dialects.postgresql import ENUM
         e1 = Enum('one','two','three', native_enum=False)
@@ -749,7 +749,7 @@ class EnumTest(TestBase):
         e1 = Enum('one','two','three', name='foo', schema='bar')
         eq_(e1.adapt(ENUM).name, 'foo')
         eq_(e1.adapt(ENUM).schema, 'bar')
-        
+
     @testing.fails_on('mysql+mysqldb', "MySQL seems to issue a 'data truncated' warning.")
     def test_constraint(self):
         assert_raises(exc.DBAPIError, 
@@ -764,7 +764,7 @@ class EnumTest(TestBase):
             non_native_enum_table.insert().execute,
             {'id':4, 'someenum':'four'}
         )
-        
+
 class BinaryTest(TestBase, AssertsExecutionResults):
     __excluded_on__ = (
         ('mysql', '<', (4, 1, 1)),  # screwy varbinary types
@@ -786,7 +786,7 @@ class BinaryTest(TestBase, AssertsExecutionResults):
                 if value:
                     value.stuff = 'this is the right stuff'
                 return value
-        
+
         metadata = MetaData(testing.db)
         binary_table = Table('binary_table', metadata,
             Column('primary_id', Integer, primary_key=True, test_needs_autoincrement=True),
@@ -855,15 +855,15 @@ class BinaryTest(TestBase, AssertsExecutionResults):
                                         'data, not really known how to make this work')
     def test_comparison(self):
         """test that type coercion occurs on comparison for binary"""
-        
+
         expr = binary_table.c.data == 'foo'
         assert isinstance(expr.right.type, LargeBinary)
-        
+
         data = os.urandom(32)
         binary_table.insert().execute(data=data)
         eq_(binary_table.select().where(binary_table.c.data==data).alias().count().scalar(), 1)
-        
-        
+
+
     def load_stream(self, name):
         f = os.path.join(os.path.dirname(__file__), "..", name)
         return open(f, mode='rb').read()
@@ -886,16 +886,16 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
                 return process
             def adapt_operator(self, op):
                 return {operators.add:operators.sub, operators.sub:operators.add}.get(op, op)
-        
+
         class MyTypeDec(types.TypeDecorator):
             impl = String
-            
+
             def process_bind_param(self, value, dialect):
                 return "BIND_IN" + str(value)
 
             def process_result_value(self, value, dialect):
                 return value + "BIND_OUT"
-            
+
         meta = MetaData(testing.db)
         test_table = Table('test', meta,
             Column('id', Integer, primary_key=True),
@@ -951,14 +951,14 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
         expr = test_table.c.bvalue == bindparam("somevalue")
         eq_(expr.right.type._type_affinity, String)
-        
+
         eq_(
             testing.db.execute(test_table.select().where(expr), 
                 {"somevalue":"foo"}).fetchall(),
             [(1, 'somedata', 
                 datetime.date(2007, 10, 15), 25, 'BIND_INfooBIND_OUT')]
         )
-    
+
     def test_literal_adapt(self):
         # literals get typed based on the types dictionary, unless
         # compatible with the left side type
@@ -974,8 +974,8 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
         expr = column('foo', CHAR) == "asdf"
         eq_(expr.right.type.__class__, CHAR)
-        
-        
+
+
     @testing.fails_on('firebird', 'Data type unknown on the parameter')
     def test_operator_adapt(self):
         """test type-based overloading of operators"""
@@ -996,7 +996,7 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
         assert testing.db.execute(select([expr.label('foo')])).scalar() == 21
 
         expr = test_table.c.avalue + literal(40, type_=MyCustomType)
-        
+
         # + operator converted to -
         # value is calculated as: (250 - (40 * 10)) / 10 == -15
         assert testing.db.execute(select([expr.label('foo')])).scalar() == -15
@@ -1007,10 +1007,10 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
     def test_typedec_operator_adapt(self):
         expr = test_table.c.bvalue + "hi"
-        
+
         assert expr.type.__class__ is MyTypeDec
         assert expr.right.type.__class__ is MyTypeDec
-        
+
         eq_(
             testing.db.execute(select([expr.label('foo')])).scalar(),
             "BIND_INfooBIND_INhiBIND_OUT"
@@ -1019,7 +1019,7 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
     def test_typedec_righthand_coercion(self):
         class MyTypeDec(types.TypeDecorator):
             impl = String
-            
+
             def process_bind_param(self, value, dialect):
                 return "BIND_IN" + str(value)
 
@@ -1028,34 +1028,34 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
         tab = table('test', column('bvalue', MyTypeDec))
         expr = tab.c.bvalue + 6
-        
+
         self.assert_compile(
             expr,
             "test.bvalue || :bvalue_1",
             use_default_dialect=True
         )
-        
+
         assert expr.type.__class__ is MyTypeDec
         eq_(
             testing.db.execute(select([expr.label('foo')])).scalar(),
             "BIND_INfooBIND_IN6BIND_OUT"
         )
-        
-        
+
+
     def test_bind_typing(self):
         from sqlalchemy.sql import column
-        
+
         class MyFoobarType(types.UserDefinedType):
             pass
-        
+
         class Foo(object):
             pass
-        
+
         # unknown type + integer, right hand bind
         # is an Integer
         expr = column("foo", MyFoobarType) + 5
         assert expr.right.type._type_affinity is types.Integer
-        
+
         # untyped bind - it gets assigned MyFoobarType
         expr = column("foo", MyFoobarType) + bindparam("foo")
         assert expr.right.type._type_affinity is MyFoobarType
@@ -1067,30 +1067,30 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
         # coerces to the left
         expr = column("foo", MyFoobarType) + Foo()
         assert expr.right.type._type_affinity is MyFoobarType
-        
+
         # including for non-commutative ops
         expr = column("foo", MyFoobarType) - Foo()
         assert expr.right.type._type_affinity is MyFoobarType
 
         expr = column("foo", MyFoobarType) - datetime.date(2010, 8, 25)
         assert expr.right.type._type_affinity is types.Date
-        
+
     def test_date_coercion(self):
         from sqlalchemy.sql import column
-        
+
         expr = column('bar', types.NULLTYPE) - column('foo', types.TIMESTAMP)
         eq_(expr.type._type_affinity, types.NullType)
-        
+
         expr = func.sysdate() - column('foo', types.TIMESTAMP)
         eq_(expr.type._type_affinity, types.Interval)
 
         expr = func.current_date() - column('foo', types.TIMESTAMP)
         eq_(expr.type._type_affinity, types.Interval)
-    
+
     def test_numerics_coercion(self):
         from sqlalchemy.sql import column
         import operator
-        
+
         for op in (
             operator.add,
             operator.mul,
@@ -1114,15 +1114,15 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
             str(column('a', types.NullType()) + column('b', types.NullType())), 
             "a + b"
         )
-        
+
     def test_expression_typing(self):
         expr = column('bar', Integer) - 3
-        
+
         eq_(expr.type._type_affinity, Integer)
 
         expr = bindparam('bar') + bindparam('foo')
         eq_(expr.type, types.NULLTYPE)
-        
+
     def test_distinct(self):
         s = select([distinct(test_table.c.avalue)])
         eq_(testing.db.execute(s).scalar(), 25)
@@ -1132,12 +1132,12 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
         assert distinct(test_table.c.data).type == test_table.c.data.type
         assert test_table.c.data.distinct().type == test_table.c.data.type
-    
+
 class CompileTest(TestBase, AssertsCompiledSQL):
     def test_default_compile(self):
         """test that the base dialect of the type object is used
         for default compilation.
-        
+
         """
         for type_, expected in (
             (String(), "VARCHAR"),
@@ -1207,8 +1207,8 @@ class DateTest(TestBase, AssertsExecutionResults):
                  datetime.time(23, 59, 59, time_micro)),
                 (10, 'colber', None, None, None),
             ]
-            
-            
+
+
             fnames = ['user_id', 'user_name', 'user_datetime',
                       'user_date', 'user_time']
 
@@ -1300,10 +1300,10 @@ class NumericTest(TestBase):
     def setup(self):
         global metadata
         metadata = MetaData(testing.db)
-        
+
     def teardown(self):
         metadata.drop_all()
-        
+
     @testing.emits_warning(r".*does \*not\* support Decimal objects natively")
     def _do_test(self, type_, input_, output, filter_ = None):
         t = Table('t', metadata, Column('x', type_))
@@ -1318,7 +1318,7 @@ class NumericTest(TestBase):
         #print result
         #print output
         eq_(result, output)
-    
+
     def test_numeric_as_decimal(self):
         self._do_test(
             Numeric(precision=8, scale=4),
@@ -1354,7 +1354,7 @@ class NumericTest(TestBase):
             [15.7563],
             filter_ = lambda n:n is not None and round(n, 5) or None
         )
-    
+
     @testing.fails_on('mssql+pymssql', 'FIXME: improve pymssql dec handling')
     def test_precision_decimal(self):
         numbers = set([
@@ -1362,7 +1362,7 @@ class NumericTest(TestBase):
             decimal.Decimal("0.004354"), 
             decimal.Decimal("900.0"), 
         ])
-            
+
         self._do_test(
             Numeric(precision=18, scale=12),
             numbers,
@@ -1372,12 +1372,12 @@ class NumericTest(TestBase):
     @testing.fails_on('mssql+pymssql', 'FIXME: improve pymssql dec handling')
     def test_enotation_decimal(self):
         """test exceedingly small decimals.
-        
+
         Decimal reports values with E notation when the exponent 
         is greater than 6.
-        
+
         """
-        
+
         numbers = set([
             decimal.Decimal('1E-2'),
             decimal.Decimal('1E-3'),
@@ -1397,7 +1397,7 @@ class NumericTest(TestBase):
             numbers,
             numbers
         )
-    
+
     @testing.fails_on("sybase+pyodbc", 
                         "Don't know how do get these values through FreeTDS + Sybase")
     @testing.fails_on("firebird", "Precision must be from 1 to 18")
@@ -1417,7 +1417,7 @@ class NumericTest(TestBase):
             numbers,
             numbers
         )
-    
+
     @testing.fails_on('sqlite', 'TODO')
     @testing.fails_on('postgresql+pg8000', 'TODO')
     @testing.fails_on("firebird", "Precision must be from 1 to 18")
@@ -1434,11 +1434,11 @@ class NumericTest(TestBase):
             numbers,
             numbers
         )
-        
+
 class NumericRawSQLTest(TestBase):
     """Test what DBAPIs and dialects return without any typing
     information supplied at the SQLA level.
-    
+
     """
     def _fixture(self, metadata, type, data):
         t = Table('t', metadata,
@@ -1446,7 +1446,7 @@ class NumericRawSQLTest(TestBase):
         )
         metadata.create_all()
         t.insert().execute(val=data)
-    
+
     @testing.fails_on('sqlite', "Doesn't provide Decimal results natively")
     @testing.provide_metadata
     def test_decimal_fp(self):
@@ -1475,16 +1475,16 @@ class NumericRawSQLTest(TestBase):
         t = self._fixture(metadata, Float, 46.583)
         val = testing.db.execute("select val from t").scalar()
         assert isinstance(val, float)
-        
+
         # some DBAPIs have unusual float handling
         if testing.against('oracle+cx_oracle', 'mysql+oursql'):
             eq_(round_decimal(val, 3), 46.583)
         else:
             eq_(val, 46.583)
-            
-        
-    
-            
+
+
+
+
 class IntervalTest(TestBase, AssertsExecutionResults):
     @classmethod
     def setup_class(cls):
@@ -1529,8 +1529,8 @@ class IntervalTest(TestBase, AssertsExecutionResults):
         eq_(row['native_interval'], None)
         eq_(row['native_interval_args'], None)
         eq_(row['non_native_interval'], None)
-    
-        
+
+
 class BooleanTest(TestBase, AssertsExecutionResults):
     @classmethod
     def setup_class(cls):
@@ -1542,14 +1542,14 @@ class BooleanTest(TestBase, AssertsExecutionResults):
             Column('unconstrained_value', Boolean(create_constraint=False)),
             )
         bool_table.create()
-        
+
     @classmethod
     def teardown_class(cls):
         bool_table.drop()
-    
+
     def teardown(self):
         bool_table.delete().execute()
-        
+
     def test_boolean(self):
         bool_table.insert().execute(id=1, value=True)
         bool_table.insert().execute(id=2, value=False)
@@ -1573,11 +1573,11 @@ class BooleanTest(TestBase, AssertsExecutionResults):
         eq_(res3, [(1, True), (2, False), 
                     (3, True), (4, True), 
                     (5, True), (6, None)])
-        
+
         # ensure we're getting True/False, not just ints
         assert res3[0][1] is True
         assert res3[1][1] is False
-    
+
     @testing.fails_on('mysql', 
             "The CHECK clause is parsed but ignored by all storage engines.")
     @testing.fails_on('mssql', 
@@ -1592,11 +1592,11 @@ class BooleanTest(TestBase, AssertsExecutionResults):
     def test_unconstrained(self):
         testing.db.execute(
             "insert into booltest (id, unconstrained_value) values (1, 5)")
-    
+
 class PickleTest(TestBase):
     def test_eq_comparison(self):
         p1 = PickleType()
-        
+
         for obj in (
             {'1':'2'},
             pickleable.Bar(5, 6),
@@ -1608,7 +1608,7 @@ class PickleTest(TestBase):
                         p1.compare_values,
                         pickleable.BrokenComparable('foo'),
                         pickleable.BrokenComparable('foo'))
-        
+
     def test_nonmutable_comparison(self):
         p1 = PickleType()
 
@@ -1618,7 +1618,7 @@ class PickleTest(TestBase):
             pickleable.OldSchool(10, 11)
         ):
             assert p1.compare_values(p1.copy_value(obj), obj)
-    
+
 class CallableTest(TestBase):
     @classmethod
     def setup_class(cls):
index 2eda4ffa840dce8542cec0a32640ea13fff40603..d6757caf1a11c50cad365568347b67f955c4eb53 100644 (file)
@@ -122,13 +122,13 @@ class EscapesDefaultsTest(testing.TestBase):
 
         try:
             engine = metadata.bind
-            
+
             # reset the identifier preparer, so that we can force it to cache
             # a unicode identifier
             engine.dialect.identifier_preparer = engine.dialect.preparer(engine.dialect)
             select([column(u'special_col')]).select_from(t1).execute().close()
             assert isinstance(engine.dialect.identifier_preparer.format_sequence(Sequence('special_col')), unicode)
-            
+
             # now execute, run the sequence.  it should run in u"Special_col.nextid" or similar as 
             # a unicode object; cx_oracle asserts that this is None or a String (postgresql lets it pass thru).
             # ensure that executioncontext._exec_default() is encoding.
index ec6402a6efc12056f566e0439f8f9362d3e9741a..0ef1293e9ba38e5ba47bfb922121603da770d62c 100644 (file)
@@ -12,7 +12,7 @@ class ZBlogTest(TestBase, AssertsExecutionResults):
     def create_tables(cls):
         tables.metadata.drop_all(bind=testing.db)
         tables.metadata.create_all(bind=testing.db)
-    
+
     @classmethod
     def drop_tables(cls):
         tables.metadata.drop_all(bind=testing.db)
@@ -33,7 +33,7 @@ class SavePostTest(ZBlogTest):
     @classmethod
     def setup_class(cls):
         super(SavePostTest, cls).setup_class()
-        
+
         mappers.zblog_mappers()
         global blog_id, user_id
         s = create_session(bind=testing.db)
@@ -54,7 +54,7 @@ class SavePostTest(ZBlogTest):
 
     def test_attach_noautoflush(self):
         """Test pending backref behavior."""
-        
+
         s = create_session(bind=testing.db, autoflush=False)
 
         s.begin()