Commits

Mike Bayer committed 546015e

- add a new sphinx extension "viewsource". takes advantage of part of the viewcode extension
to allow ad-hoc display of the source of any file, as well as a "directory listing" structure.
- reorganize examples/ to take advantage of new extension. in particular, keep moving all
the descriptive text for files etc. into module docstrings, taking more advantage of
self-documentation.

Comments (0)

Files changed (37)

doc/build/builder/viewsource.py

+from docutils import nodes
+from sphinx.ext.viewcode import collect_pages
+from sphinx.pycode import ModuleAnalyzer
+import imp
+from sphinx import addnodes
+import re
+from sphinx.util.compat import Directive
+import os
+from docutils.statemachine import StringList
+from sphinx.environment import NoUri
+
+def view_source(name, rawtext, text, lineno, inliner,
+                      options={}, content=[]):
+
+    env = inliner.document.settings.env
+
+    node = _view_source_node(env, text, None)
+    return [node], []
+
+def _view_source_node(env, text, state):
+    # pretend we're using viewcode fully,
+    # install the context it looks for
+    if not hasattr(env, '_viewcode_modules'):
+        env._viewcode_modules = {}
+
+    modname = text
+    text = modname.split(".")[-1] + ".py"
+
+    # imitate sphinx .<modname> syntax
+    if modname.startswith("."):
+        # see if the modname needs to be corrected in terms
+        # of current module context
+        base_module = env.temp_data.get('autodoc:module')
+        if base_module is None:
+            base_module = env.temp_data.get('py:module')
+
+        if base_module:
+            modname = base_module + modname
+
+    urito = env.app.builder.get_relative_uri
+
+    # we're showing code examples which may have dependencies
+    # which we really don't want to have required so load the
+    # module by file, not import (though we are importing)
+    # the top level module here...
+    pathname = None
+    for token in modname.split("."):
+        file_, pathname, desc = imp.find_module(token, [pathname] if pathname else None)
+        if file_:
+            file_.close()
+
+    # unlike viewcode which silently traps exceptions,
+    # I want this to totally barf if the file can't be loaded.
+    # a failed build better than a complete build missing
+    # key content
+    analyzer = ModuleAnalyzer.for_file(pathname, modname)
+    # copied from viewcode
+    analyzer.find_tags()
+    if not isinstance(analyzer.code, unicode):
+        code = analyzer.code.decode(analyzer.encoding)
+    else:
+        code = analyzer.code
+
+    if state is not None:
+        docstring = _find_mod_docstring(analyzer)
+        if docstring:
+            # get rid of "foo.py" at the top
+            docstring = re.sub(r"^[a-zA-Z_0-9]+\.py", "", docstring)
+
+            # strip
+            docstring = docstring.strip()
+
+            # yank only first paragraph
+            docstring = docstring.split("\n\n")[0].strip()
+    else:
+        docstring = None
+
+    entry = code, analyzer.tags, {}
+    env._viewcode_modules[modname] = entry
+    pagename = '_modules/' + modname.replace('.', '/')
+
+    try:
+        refuri = urito(env.docname, pagename)
+    except NoUri:
+        # if we're in the latex builder etc., this seems
+        # to be what we get
+        refuri = None
+
+
+    if docstring:
+        # embed the ref with the doc text so that it isn't
+        # a separate paragraph
+        if refuri:
+            docstring = "`%s <%s>`_ - %s" % (text, refuri, docstring)
+        else:
+            docstring = "``%s`` - %s" % (text, docstring)
+        para = nodes.paragraph('', '')
+        state.nested_parse(StringList([docstring]), 0, para)
+        return_node = para
+    else:
+        if refuri:
+            refnode = nodes.reference('', '',
+                    nodes.Text(text, text),
+                    refuri=urito(env.docname, pagename)
+                )
+        else:
+            refnode = nodes.Text(text, text)
+
+        if state:
+            return_node = nodes.paragraph('', '', refnode)
+        else:
+            return_node = refnode
+
+    return return_node
+
+from sphinx.pycode.pgen2 import token
+
+def _find_mod_docstring(analyzer):
+    """attempt to locate the module-level docstring.
+
+    Note that sphinx autodoc just uses ``__doc__``.  But we don't want
+    to import the module, so we need to parse for it.
+
+    """
+    analyzer.tokenize()
+    for type_, parsed_line, start_pos, end_pos, raw_line in analyzer.tokens:
+        if type_ == token.COMMENT:
+            continue
+        elif type_ == token.STRING:
+            return eval(parsed_line)
+        else:
+            return None
+
+def _parse_content(content):
+    d = {}
+    d['text'] = []
+    idx = 0
+    for line in content:
+        idx += 1
+        m = re.match(r' *\:(.+?)\:(?: +(.+))?', line)
+        if m:
+            attrname, value = m.group(1, 2)
+            d[attrname] = value or ''
+        else:
+            break
+    d["text"] = content[idx:]
+    return d
+
+def _comma_list(text):
+    return re.split(r"\s*,\s*", text.strip())
+
+class AutoSourceDirective(Directive):
+    has_content = True
+
+    def run(self):
+        content = _parse_content(self.content)
+
+
+        env = self.state.document.settings.env
+        self.docname = env.docname
+
+        sourcefile = self.state.document.current_source.split(":")[0]
+        dir_ = os.path.dirname(sourcefile)
+        files = [
+            f for f in os.listdir(dir_) if f.endswith(".py")
+            and f != "__init__.py"
+        ]
+
+        if "files" in content:
+            # ordered listing of files to include
+            files = [fname for fname in _comma_list(content["files"])
+                        if fname in set(files)]
+
+        node = nodes.paragraph('', '',
+                        nodes.Text("Listing of files:", "Listing of files:")
+                )
+
+        bullets = nodes.bullet_list()
+        for fname in files:
+            modname, ext = os.path.splitext(fname)
+            # relative lookup
+            modname = "." + modname
+
+            link = _view_source_node(env, modname, self.state)
+
+            list_node = nodes.list_item('',
+                link
+            )
+            bullets += list_node
+
+        node += bullets
+
+        return [node]
+
+def setup(app):
+    app.add_role('viewsource', view_source)
+
+    app.add_directive('autosource', AutoSourceDirective)
+
+    # from sphinx.ext.viewcode
+    app.connect('html-collect-pages', collect_pages)

doc/build/conf.py

 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 sys.path.insert(0, os.path.abspath('../../lib'))
-sys.path.insert(0, os.path.abspath('../../examples'))
+sys.path.insert(0, os.path.abspath('../..')) # examples
 sys.path.insert(0, os.path.abspath('.'))
 
 import sqlalchemy
                 'builder.dialect_info',
                 'builder.mako',
                 'builder.sqlformatter',
+                'builder.viewsource',
             ]
 
 # Add any paths that contain templates here, relative to this directory.

doc/build/orm/examples.rst

 Additional SQLAlchemy examples, some user contributed, are available on the
 wiki at `<http://www.sqlalchemy.org/trac/wiki/UsageRecipes>`_.
 
+
 .. _examples_adjacencylist:
 
 Adjacency List
 --------------
 
-Location: /examples/adjacency_list/
-
-.. automodule:: adjacency_list
+.. automodule:: examples.adjacency_list
 
 .. _examples_associations:
 
 Associations
 ------------
 
-Location: /examples/association/
-
-.. automodule:: association
+.. automodule:: examples.association
 
 
 .. _examples_instrumentation:
 Attribute Instrumentation
 -------------------------
 
-Location: /examples/custom_attributes/
-
-.. automodule:: custom_attributes
+.. automodule:: examples.custom_attributes
 
 .. _examples_caching:
 
 Dogpile Caching
 ---------------
 
-Location: /examples/dogpile_caching/
-
-.. automodule:: dogpile_caching
+.. automodule:: examples.dogpile_caching
 
 Directed Graphs
 ---------------
 
-Location: /examples/graphs/
-
-.. automodule:: graphs
+.. automodule:: examples.graphs
 
 Dynamic Relations as Dictionaries
 ----------------------------------
 
-Location: /examples/dynamic_dict/
-
-.. automodule:: dynamic_dict
+.. automodule:: examples.dynamic_dict
 
 .. _examples_generic_associations:
 
 Generic Associations
 --------------------
 
-Location: /examples/generic_associations
-
-.. automodule:: generic_associations
+.. automodule:: examples.generic_associations
 
 .. _examples_sharding:
 
 Horizontal Sharding
 -------------------
 
-Location: /examples/sharding
-
-.. automodule:: sharding
+.. automodule:: examples.sharding
 
 Inheritance Mappings
 --------------------
 
-Location: /examples/inheritance/
-
-.. automodule:: inheritance
+.. automodule:: examples.inheritance
 
 Large Collections
 -----------------
 
-Location: /examples/large_collection/
-
-.. automodule:: large_collection
+.. automodule:: examples.large_collection
 
 Nested Sets
 -----------
 
-Location: /examples/nested_sets/
-
-.. automodule:: nested_sets
-
-Polymorphic Associations
-------------------------
-
-See :ref:`examples_generic_associations` for a modern version of polymorphic associations.
+.. automodule:: examples.nested_sets
 
 .. _examples_postgis:
 
 PostGIS Integration
 -------------------
 
-Location: /examples/postgis
-
-.. automodule:: postgis
+.. automodule:: examples.postgis
 
 Versioned Objects
 -----------------
 
-Location: /examples/versioning
-
-.. automodule:: versioning
+.. automodule:: examples.versioning
 
 Vertical Attribute Mapping
 --------------------------
 
-Location: /examples/vertical
-
-.. automodule:: vertical
+.. automodule:: examples.vertical
 
 .. _examples_xmlpersistence:
 
 XML Persistence
 ---------------
 
-Location: /examples/elementtree/
-
-.. automodule:: elementtree
+.. automodule:: examples.elementtree

examples/adjacency_list/__init__.py

 
     dump_tree(node)
 
+.. autosource::
+
 """
 

examples/association/__init__.py

 """
-
 Examples illustrating the usage of the "association object" pattern,
 where an intermediary class mediates the relationship between two
 classes that are associated in a many-to-many pattern.
 
-This directory includes the following examples:
-
-* basic_association.py - illustrate a many-to-many relationship between an
-  "Order" and a collection of "Item" objects, associating a purchase price
-  with each via an association object called "OrderItem"
-* proxied_association.py - same example as basic_association, adding in
-  usage of :mod:`sqlalchemy.ext.associationproxy` to make explicit references
-  to "OrderItem" optional.
-* dict_of_sets_with_default.py - an advanced association proxy example which
-  illustrates nesting of association proxies to produce multi-level Python
-  collections, in this case a dictionary with string keys and sets of integers
-  as values, which conceal the underlying mapped classes.
+.. autosource::
 
 """

examples/association/basic_association.py

-"""A basic example of using the association object pattern.
+"""basic_association.py
+
+illustrate a many-to-many relationship between an
+"Order" and a collection of "Item" objects, associating a purchase price
+with each via an association object called "OrderItem"
 
 The association object pattern is a form of many-to-many which
 associates additional data with each association between parent/child.

examples/association/dict_of_sets_with_default.py

-"""Illustrate a 'dict of sets of integers' model.
+"""dict_of_sets_with_default.py
+
+an advanced association proxy example which
+illustrates nesting of association proxies to produce multi-level Python
+collections, in this case a dictionary with string keys and sets of integers
+as values, which conceal the underlying mapped classes.
 
 This is a three table model which represents a parent table referencing a
 dictionary of string keys and sets as values, where each set stores a

examples/association/proxied_association.py

-"""An extension to the basic_association.py example, which illustrates
-the usage of sqlalchemy.ext.associationproxy.
+"""proxied_association.py
+
+same example as basic_association, adding in
+usage of :mod:`sqlalchemy.ext.associationproxy` to make explicit references
+to ``OrderItem`` optional.
+
 
 """
 

examples/custom_attributes/__init__.py

 Two examples illustrating modifications to SQLAlchemy's attribute management
 system.
 
-``listen_for_events.py`` illustrates the usage of
-:class:`~sqlalchemy.orm.interfaces.AttributeExtension` to intercept attribute
-events.  It additionally illustrates a way to automatically attach these
-listeners to all class attributes using a
-:class:`.InstrumentationManager`.
-
-``custom_management.py`` illustrates much deeper usage of
-:class:`.InstrumentationManager` as well as
-collection adaptation, to completely change the underlying method used to
-store state on an object.   This example was developed to illustrate
-techniques which would be used by other third party object instrumentation
-systems to interact with SQLAlchemy's event system and is only intended for
-very intricate framework integrations.
+.. autosource::
 
 """

examples/dogpile_caching/__init__.py

 
    python examples/dogpile_caching/local_session_caching.py
 
-
-Listing of files:
-
-    environment.py - Establish the Session, a dictionary
-    of "regions", a sample cache region against a .dbm
-    file, data / cache file paths, and configurations,
-    bootstrap fixture data if necessary.
-
-    caching_query.py - Represent functions and classes
-    which allow the usage of Dogpile caching with SQLAlchemy.
-    Introduces a query option called FromCache.
-
-    model.py - The datamodel, which represents Person that has multiple
-    Address objects, each with PostalCode, City, Country
-
-    fixture_data.py - creates demo PostalCode, Address, Person objects
-    in the database.
-
-    helloworld.py - the basic idea.
-
-    relationship_caching.py - Illustrates how to add cache options on
-    relationship endpoints, so that lazyloads load from cache.
-
-    advanced.py - Further examples of how to use FromCache.  Combines
-    techniques from the first two scripts.
-
-    local_session_caching.py - Grok everything so far ?   This example
-    creates a new dogpile.cache backend that will persist data in a dictionary
-    which is local to the current session.   remove() the session
-    and the cache is gone.
+.. autosource::
+    :files: environment.py, caching_query.py, model.py, fixture_data.py, \
+          helloworld.py, relationship_caching.py, advanced.py, \
+          local_session_caching.py
 
 """

examples/dogpile_caching/caching_query.py

 """caching_query.py
 
-Represent persistence structures which allow the usage of
-dogpile.cache caching with SQLAlchemy.
+Represent functions and classes
+which allow the usage of Dogpile caching with SQLAlchemy.
+Introduces a query option called FromCache.
 
 The three new concepts introduced here are:
 

examples/dogpile_caching/local_session_caching.py

 """local_session_caching.py
 
+Grok everything so far ?   This example
+creates a new dogpile.cache backend that will persist data in a dictionary
+which is local to the current session.   remove() the session
+and the cache is gone.
+
 Create a new Dogpile cache backend that will store
 cached data local to the current Session.
 

examples/dogpile_caching/model.py

-"""Model.   We are modeling Person objects with a collection
-of Address objects.  Each Address has a PostalCode, which
-in turn references a City and then a Country:
+"""model.py
+
+The datamodel, which represents Person that has multiple
+Address objects, each with PostalCode, City, Country.
 
 Person --(1..n)--> Address
 Address --(has a)--> PostalCode

examples/dogpile_caching/relation_caching.py

-"""relationship_caching.py
-
-Load a set of Person and Address objects, specifying that
-related PostalCode, City, Country objects should be pulled from long
-term cache.
-
-"""
-from .environment import Session, root
-from .model import Person, cache_address_bits
-from sqlalchemy.orm import joinedload
-import os
-
-for p in Session.query(Person).options(joinedload(Person.addresses), cache_address_bits):
-    print(p.format_full())
-
-
-print("\n\nIf this was the first run of relationship_caching.py, SQL was likely emitted to "\
-        "load postal codes, cities, countries.\n"\
-        "If run a second time, assuming the cache is still valid, "\
-        "only a single SQL statement will run - all "\
-        "related data is pulled from cache.\n"\
-        "To clear the cache, delete the file %r.  \n"\
-        "This will cause a re-load of cities, postal codes and countries on "\
-        "the next run.\n"\
-        % os.path.join(root, 'cache.dbm'))

examples/dogpile_caching/relationship_caching.py

+"""relationship_caching.py
+
+Illustrates how to add cache options on
+relationship endpoints, so that lazyloads load from cache.
+
+Load a set of Person and Address objects, specifying that
+related PostalCode, City, Country objects should be pulled from long
+term cache.
+
+"""
+from .environment import Session, root
+from .model import Person, cache_address_bits
+from sqlalchemy.orm import joinedload
+import os
+
+for p in Session.query(Person).options(joinedload(Person.addresses), cache_address_bits):
+    print(p.format_full())
+
+
+print("\n\nIf this was the first run of relationship_caching.py, SQL was likely emitted to "\
+        "load postal codes, cities, countries.\n"\
+        "If run a second time, assuming the cache is still valid, "\
+        "only a single SQL statement will run - all "\
+        "related data is pulled from cache.\n"\
+        "To clear the cache, delete the file %r.  \n"\
+        "This will cause a re-load of cities, postal codes and countries on "\
+        "the next run.\n"\
+        % os.path.join(root, 'cache.dbm'))

examples/dynamic_dict/__init__.py

 string keys) can operate upon a large collection without loading the
 full collection at once.
 
+.. autosource::
+
 """

examples/elementtree/__init__.py

 suit any kind of DOM representation system. Querying along
 xpath-like strings is illustrated as well.
 
-In order of complexity:
-
-* ``pickle.py`` - Quick and dirty, serialize the whole DOM into a BLOB
-  column.  While the example   is very brief, it has very limited
-  functionality.
-
-* ``adjacency_list.py`` - Each DOM node is stored in an individual
-  table row, with attributes   represented in a separate table.  The
-  nodes are associated in a hierarchy using an adjacency list
-  structure.  A query function is introduced which can search for nodes
-  along any path with a given   structure of attributes, basically a
-  (very narrow) subset of xpath.
-
-* ``optimized_al.py`` - Uses the same strategy as
-  ``adjacency_list.py``, but associates each   DOM row with its owning
-  document row, so that a full document of DOM nodes can be   loaded
-  using O(1) queries - the construction of the "hierarchy" is performed
-  after the load in a non-recursive fashion and is much more
-  efficient.
-
 E.g.::
 
     # parse an XML file and persist in the database
         # dump the XML
         print document
 
+.. autosource::
+    :files: pickle.py, adjacency_list.py, optimized_al.py
+
 """

examples/elementtree/adjacency_list.py

-"""illustrates an explicit way to persist an XML document expressed using ElementTree.
+"""Illustrates an explicit way to persist an XML document expressed using ElementTree.
+
+Each DOM node is stored in an individual
+table row, with attributes   represented in a separate table.  The
+nodes are associated in a hierarchy using an adjacency list
+structure.  A query function is introduced which can search for nodes
+along any path with a given   structure of attributes, basically a
+(very narrow) subset of xpath.
 
 This example explicitly marshals/unmarshals the ElementTree document into
 mapped entities which have their own tables.  Compare to pickle.py which
 uses pickle to accomplish the same task.  Note that the usage of both
 styles of persistence are identical, as is the structure of the main Document class.
+
 """
 
 ################################# PART I - Imports/Coniguration ####################################

examples/elementtree/optimized_al.py

-"""This script duplicates adjacency_list.py, but optimizes the loading
-of XML nodes to be based on a "flattened" datamodel. Any number of XML documents,
-each of arbitrary complexity, can be loaded in their entirety via a single query
-which joins on only three tables.
+"""Uses the same strategy as
+  ``adjacency_list.py``, but associates each   DOM row with its owning
+  document row, so that a full document of DOM nodes can be loaded
+  using O(1) queries - the construction of the "hierarchy" is performed
+  after the load in a non-recursive fashion and is more
+  efficient.
 
 """
 

examples/generic_associations/__init__.py

 parent class is provided with an ``addresses`` collection
 which contains ``Address`` objects.
 
-The configurations include:
-
-* ``table_per_related.py`` - illustrates a distinct table per related collection.
-* ``table_per_association.py`` - illustrates a shared collection table, using a
-  table per association.
-* ``discriminator_on_association.py`` - shared collection table and shared
-  association table, including a discriminator column.
-* ``generic_fk.py`` - imitates the approach taken by popular frameworks such
-  as Django and Ruby on Rails to create a so-called "generic foreign key".
-
-The ``discriminator_on_association.py`` and ``generic_fk.py`` scripts
+The :viewsource:`.discriminator_on_association` and :viewsource:`.generic_fk` scripts
 are modernized versions of recipes presented in the 2007 blog post
 `Polymorphic Associations with SQLAlchemy <http://techspot.zzzeek.org/2007/05/29/polymorphic-associations-with-sqlalchemy/>`_.
-.
+
+.. autosource::
 
 """

examples/generic_associations/discriminator_on_association.py

 """discriminator_on_related.py
 
-The HasAddresses mixin will provide a relationship
-to the fixed Address table based on a fixed association table.
-
-The association table contains a "discriminator"
-which determines what type of parent object associates to the
-Address row.  SQLAlchemy's single-table-inheritance feature is used
+Illustrates a mixin which provides a generic association
+using a single target table and a single association table,
+referred to by all parent tables.  The association table
+contains a "discriminator" column which determines what type of
+parent object associates to each particular row in the association
+table.
+
+SQLAlchemy's single-table-inheritance feature is used
 to target different association types.
 
-This is a "polymorphic association".   Even though a "discriminator"
-that refers to a particular table is present, the extra association
-table is used so that traditional foreign key constraints may be used.
-
 This configuration attempts to simulate a so-called "generic foreign key"
 as closely as possible without actually foregoing the use of real
 foreign keys.   Unlike table-per-related and table-per-association,

examples/generic_associations/generic_fk.py

 """generic_fk.py
 
-This example will emulate key aspects of the system used by popular
-frameworks such as Django, ROR, etc.
-
-It approaches the issue by bypassing standard referential integrity
-practices, and producing a so-called "generic foreign key", which means
-a database column that is not constrained to refer to any particular table.
-In-application logic is used to determine which table is referenced.
+Illustrates a so-called "generic foreign key", in a similar fashion
+to that of popular frameworks such as Django, ROR, etc.  This
+approach bypasses standard referential integrity
+practices, in that the "foreign key" column is not actually
+constrained to refer to any particular table; instead,
+in-application logic is used to determine which table is referenced.
 
 This approach is not in line with SQLAlchemy's usual style, as foregoing
 foreign key integrity means that the tables can easily contain invalid

examples/generic_associations/table_per_association.py

 """table_per_association.py
 
-The HasAddresses mixin will provide a new "address_association" table for
-each parent class.   The "address" table will be shared
-for all parents.
+Illustrates a mixin which provides a generic association
+via a individually generated association tables for each parent class.
+The associated objects themselves are persisted in a single table
+shared among all parents.
 
 This configuration has the advantage that all Address
 rows are in one table, so that the definition of "Address"

examples/generic_associations/table_per_related.py

 """table_per_related.py
 
-The HasAddresses mixin will provide a new "address" table for
-each parent class, as well as a distinct "Address" subclass.
+Illustrates a generic association which persists association
+objects within individual tables, each one generated to persist
+those objects on behalf of a particular parent class.
 
 This configuration has the advantage that each type of parent
 maintains its "Address" rows separately, so that collection

examples/graphs/__init__.py

     n2.add_neighbor(n5)
     print n2.higher_neighbors()
 
+.. autosource::
+
 """

examples/inheritance/__init__.py

 """Working examples of single-table, joined-table, and concrete-table
 inheritance as described in :ref:`datamapping_inheritance`.
 
+.. autosource::
+
 """

examples/inheritance/concrete.py

+"""Concrete (table-per-class) inheritance example."""
+
 from sqlalchemy import create_engine, MetaData, Table, Column, Integer, \
     String
 from sqlalchemy.orm import mapper, sessionmaker, polymorphic_union

examples/inheritance/joined.py

-"""this example illustrates a polymorphic load of two classes"""
+"""Joined-table (table-per-subclass) inheritance example."""
 
 from sqlalchemy import Table, Column, Integer, String, \
     ForeignKey, create_engine, inspect, or_

examples/inheritance/single.py

+"""Single-table inheritance example."""
+
 from sqlalchemy import MetaData, Table, Column, Integer, String, \
     ForeignKey, create_engine
 from sqlalchemy.orm import mapper, relationship, sessionmaker

examples/large_collection/__init__.py

   ``passive_deletes=True`` to greatly improve the performance of
   related collection deletion.
 
+.. autosource::
+
 """

examples/nested_sets/__init__.py

 """ Illustrates a rudimentary way to implement the "nested sets"
 pattern for hierarchical data using the SQLAlchemy ORM.
 
+.. autosource::
+
 """

examples/postgis/__init__.py

 
     print session.query(Road).filter(Road.road_geom.intersects(r1.road_geom)).all()
 
+.. autosource::
+
 """
 

examples/sharding/__init__.py

 database nodes) in an explicit way - described on the wiki at
 `EntityName <http://www.sqlalchemy.org/trac/wiki/UsageRecipes/EntityName>`_.
 
+.. autosource::
+
 """

examples/versioning/__init__.py

 
     SomeHistoryClass = SomeClass.__history_mapper__.class_
 
+.. autosource::
+
 """

examples/versioning/history_meta.py

+"""Versioned mixin class and other utilities."""
+
 from sqlalchemy.ext.declarative import declared_attr
 from sqlalchemy.orm import mapper, class_mapper, attributes, object_mapper
 from sqlalchemy.orm.exc import UnmappedClassError, UnmappedColumnError

examples/versioning/test_versioning.py

+"""Unit tests illustrating usage of the ``history_meta.py`` module functions."""
+
 from unittest import TestCase
 from sqlalchemy.ext.declarative import declarative_base
 from .history_meta import Versioned, versioned_session

examples/vertical/__init__.py

                 AnimalFact.value == True))))
     print 'weasel-like animals', q.all()
 
+.. autosource::
 
 """
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.