Commits

Mike Bayer committed d5be0a2

- rework setup.py script to work with:
- Python 3
- Python 3 builds if Distribute isn't installed
- rework install documentation again
- raise if doc build with mako < 0.4.1
- Python 3.1 builds force doctest parse but then fails due to distribute bug,
so remove usage of backslash \\ in hybrid.py docstring
- put in the latest ez_setup.py

Comments (0)

Files changed (5)

doc/build/builder/builders.py

 import re
 from mako.lookup import TemplateLookup
 from mako.template import Template
+from mako import __version__
+
+if __version__ < "0.4.1":
+    raise Exception("Mako 0.4.1 or greater is required for "
+                        "documentation build.")
 
 class MakoBridge(TemplateBridge):
     def init(self, builder, *args, **kw):

doc/build/intro.rst

 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
 
 In :ref:`core_toplevel`, the breadth of SQLAlchemy's SQL and database
 integration and description services are documented, the core of which is the
-SQL Expression language.  The SQL Expression Language is a toolkit all its own, independent of the ORM package, which can be used to construct manipulable SQL
+SQL Expression language. The SQL Expression Language is a toolkit all its own,
+independent of the ORM package, which can be used to construct manipulable SQL
 expressions which can be programmatically constructed, modified, and executed,
-returning cursor-like result sets.  In contrast to the ORM's domain-centric
+returning cursor-like result sets. In contrast to the ORM's domain-centric
 mode of usage, the expression language provides a schema-centric usage
-paradigm.  New users should begin here with :ref:`sqlexpression_toplevel`.
+paradigm. New users should begin here with :ref:`sqlexpression_toplevel`.
 SQLAlchemy engine, connection, and pooling services are also described in
 :ref:`core_toplevel`.
 
 
 There is also a wide variety of examples involving both core SQLAlchemy
 constructs as well as the ORM on the wiki.  See
-`<http://www.sqlalchemy.org/trac/wiki/UsageRecipes>`_.
+`Theatrum Chemicum <http://www.sqlalchemy.org/trac/wiki/UsageRecipes>`_.
 
 .. _installation:
 
 Installation Guide
 ==================
 
-SQLAlchemy builds using the standard `Python Distutils <http://docs.python.org/distutils/>`_ approach.   
+Supported Platforms
+-------------------
 
-Installing with setuptools or pip
-----------------------------------
+SQLAlchemy has been tested against the following platforms:
 
-Installing SQLAlchemy from scratch is most easily achieved with `setuptools
-<http://pypi.python.org/pypi/setuptools/>`_, or alternatively
-`pip <http://pypi.python.org/pypi/pip/>`_. Assuming it's installed, just run this from the command-line:
+* cPython since version 2.4, through the 2.xx series
+* cPython version 3, throughout all 3.xx series
+* `Jython <http://www.jython.org/>`_ 2.5 or greater
+* `Pypy <http://pypy.org/>`_ 1.5 or greater
 
-.. sourcecode:: none
+Supported Installation Methods
+-------------------------------
 
-    # easy_install SQLAlchemy
+SQLAlchemy supports installation using standard Python "distutils" or
+"setuptools" methodologies. An overview of potential setups is as follows:
 
-Or with pip:
+* **Plain Python Distutils** - SQLAlchemy can be installed with a clean
+  Python install using the services provided via `Python Distutils <http://docs.python.org/distutils/>`_,
+  using the ``setup.py`` script. The C extensions as well as Python 3 builds are supported.
+* **Standard Setuptools** - When using `setuptools <http://pypi.python.org/pypi/setuptools/>`_, 
+  SQLAlchemy can be installed via ``setup.py`` or ``easy_install``, and the C
+  extensions are supported.  setuptools is not supported on Python 3 at the time
+  of of this writing.
+* **Distribute** - With `distribute <http://pypi.python.org/pypi/distribute/>`_, 
+  SQLAlchemy can be installed via ``setup.py`` or ``easy_install``, and the C
+  extensions as well as Python 3 builds are supported.
+* **pip** - `pip <http://pypi.python.org/pypi/pip/>`_ is an installer that
+  rides on top of ``setuptools`` or ``distribute``, replacing the usage
+  of ``easy_install``.  It is often preferred for its simpler mode of usage.
 
-.. sourcecode:: none
+Install via easy_install or pip
+-------------------------------
 
-    # pip install SQLAlchemy
+When ``easy_install`` or ``pip`` is available, the distribution can be 
+downloaded from Pypi and installed in one step::
+
+    easy_install SQLAlchemy
+
+Or with pip::
+
+    pip install SQLAlchemy
 
 This command will download the latest version of SQLAlchemy from the `Python
 Cheese Shop <http://pypi.python.org/pypi/SQLAlchemy>`_ and install it to your system.
 Installing using setup.py
 ----------------------------------
 
-Otherwise, you can install from the distribution using the ``setup.py`` script:
+Otherwise, you can install from the distribution using the ``setup.py`` script::
 
-.. sourcecode:: none
-
-    # python setup.py install
+    python setup.py install
 
 Installing the C Extensions
 ----------------------------------
 
-SQLAlchemy includes C extensions which provide an extra speed boost for dealing with result sets.   These extensions build automatically when the build or install commands of setup.py are invoked.  If the C extensions cannot be built, the setup process will output a warning message.
+SQLAlchemy includes C extensions which provide an extra speed boost for
+dealing with result sets. Currently, the extensions are only supported on the
+2.xx series of cPython, not Python 3 or Pypy.
 
-To disable building the C extensions, pass the flag ``--with-no-cextensions`` to the ``setup.py`` script.
+setup.py will automatically build the extensions if an appropriate platform is
+detected. If the build of the C extensions fails, due to missing compiler or
+other issue, the setup process will output a warning message, and re-run the
+build without the C extensions, upon completion reporting final status.
+
+To run the build/install without even attempting to compile the C extensions,
+pass the flag ``--without-cextensions`` to the ``setup.py`` script::
+
+    python setup.py --without-cextensions install
 
 Installing on Python 3
 ----------------------------------
 
-SQLAlchemy ships as Python 2 code.   For Python 3 usage, the ``setup.py`` script will invoke the Python ``2to3`` tool on the build, plugging in an extra "preprocessor" as well.   Using the Python 3 interpreter with ``setup.py`` or a Python 3 version of easy_install or pip is all that's needed.
+SQLAlchemy ships as Python 2 code. For Python 3 usage, the ``setup.py`` script
+will invoke the Python ``2to3`` tool on the build, plugging in an extra
+"preprocessor" as well. The 2to3 step works with Python distutils
+(part of the standard Python install) and Distribute - it will **not**
+work with a non-Distribute setuptools installation.
 
 Installing a Database API
 ----------------------------------
 
-SQLAlchemy is designed to operate with a `DB-API <http://www.python.org/doc/peps/pep-0249/>`_ implementation built for a particular database, and includes support for the most popular databases.  The current list is at :ref:`supported_dbapis`.
+SQLAlchemy is designed to operate with a `DB-API
+<http://www.python.org/doc/peps/pep-0249/>`_ implementation built for a
+particular database, and includes support for the most popular databases. The
+current list is at :ref:`supported_dbapis`.
 
 Checking the Installed SQLAlchemy Version
 ------------------------------------------
 
-This documentation covers SQLAlchemy version 0.7.  If you're working on a system that already has SQLAlchemy installed, check the version from your Python prompt like this:
+This documentation covers SQLAlchemy version 0.7. If you're working on a
+system that already has SQLAlchemy installed, check the version from your
+Python prompt like this:
 
 .. sourcecode:: python+sql
 
 0.6 to 0.7 Migration
 =====================
 
-Notes on what's changed from 0.6 to 0.7 is available on the SQLAlchemy wiki at `07Migration <http://www.sqlalchemy.org/trac/wiki/07Migration>`_.
+Notes on what's changed from 0.6 to 0.7 is available on the SQLAlchemy wiki at
+`07Migration <http://www.sqlalchemy.org/trac/wiki/07Migration>`_.
 This file can also be run as a script to install or upgrade setuptools.
 """
 import sys
-DEFAULT_VERSION = "0.6c9"
+DEFAULT_VERSION = "0.6c11"
 DEFAULT_URL     = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
 
 md5_data = {
     'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
     'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
     'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
+    'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
+    'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
+    'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
+    'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
+    'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
+    'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
+    'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
+    'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
     'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
     'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
     'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
     try:
         import pkg_resources
     except ImportError:
-        return do_download()
+        return do_download()       
     try:
         pkg_resources.require("setuptools>="+version); return
     except pkg_resources.VersionConflict, e:
             "\n\n(Currently using %r)"
             ) % (version, e.args[0])
             sys.exit(2)
-        else:
-            del pkg_resources, sys.modules['pkg_resources']    # reload ok
-            return do_download()
     except pkg_resources.DistributionNotFound:
-        return do_download()
+        pass
+
+    del pkg_resources, sys.modules['pkg_resources']    # reload ok
+    return do_download()
 
 def download_setuptools(
     version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,

lib/sqlalchemy/ext/hybrid.py

     FROM interval 
     WHERE interval.start <= :start_1 AND interval."end" > :end_1
 
-    >>>  ia = aliased(Interval)
+    >>> ia = aliased(Interval)
     >>> print Session().query(Interval, ia).filter(Interval.intersects(ia))
     SELECT interval.id AS interval_id, interval.start AS interval_start, 
     interval."end" AS interval_end, interval_1.id AS interval_1_id, 
 would use an outer join::
 
     >>> from sqlalchemy import or_
-    >>> print Session().query(User, User.balance).outerjoin(User.accounts).\\
-    ...         filter(or_(User.balance < 5000, User.balance == None))
+    >>> print (Session().query(User, User.balance).outerjoin(User.accounts).
+    ...         filter(or_(User.balance < 5000, User.balance == None)))
     SELECT "user".id AS user_id, "user".name AS user_name, account.balance AS account_balance 
     FROM "user" LEFT OUTER JOIN account ON "user".id = account.user_id 
     WHERE account.balance <  :balance_1 OR account.balance IS NULL
                               DistutilsPlatformError)
 try:
     from setuptools import setup, Extension, Feature
+    has_setuptools = True
 except ImportError:
+    has_setuptools = False
     from distutils.core import setup, Extension
     Feature = None
+    try:  # Python 3
+        from distutils.command.build_py import build_py_2to3 as build_py
+    except ImportError:  # Python 2
+        from distutils.command.build_py import build_py
 
+cmdclass = {}
 pypy = hasattr(sys, 'pypy_version_info')
 py3k = False
 extra = {}
     from lib2to3.refactor import RefactoringTool
     RefactoringTool.refactor_string = refactor_string
 
-    extra.update(
-        use_2to3=True,
-    )
+    if has_setuptools:
+        extra.update(
+            use_2to3=True,
+        )
+    else:
+        cmdclass['build_py'] = build_py
 
 ext_modules = [
     Extension('sqlalchemy.cprocessors',
 if sys.platform == 'win32' and sys.version_info > (2, 6):
    # 2.6's distutils.msvc9compiler can raise an IOError when failing to
    # find the compiler
-   ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError,
-                 IOError)
+   ext_errors = (
+                    CCompilerError, DistutilsExecError, 
+                    DistutilsPlatformError, IOError)
 else:
    ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError)
 
 class BuildFailed(Exception):
 
-    def __init__(self, cause):
-        self.cause = cause
+    def __init__(self):
+        self.cause = sys.exc_info()[1] # work around py 2/3 different syntax
 
 class ve_build_ext(build_ext):
     # This class allows C extension building to fail.
     def run(self):
         try:
             build_ext.run(self)
-        except DistutilsPlatformError, exc:
-            raise BuildFailed(exc)
+        except DistutilsPlatformError:
+            raise BuildFailed()
 
     def build_extension(self, ext):
         try:
             build_ext.build_extension(self, ext)
-        except ext_errors, exc:
-            raise BuildFailed(exc)
+        except ext_errors:
+            raise BuildFailed()
+
+cmdclass['build_ext'] = ve_build_ext
+
+def status_msgs(*msgs):
+    print('*' * 75)
+    for msg in msgs:
+        print(msg)
+    print('*' * 75)
 
 def find_packages(dir_):
     packages = []
     for pkg in ['sqlalchemy']:
-        for _dir, subdirectories, files in os.walk(os.path.join(dir_, pkg)):
+        for _dir, subdirectories, files in (
+                os.walk(os.path.join(dir_, pkg))
+            ):
             if '__init__.py' in files:
                 lib, fragment = _dir.split(os.sep, 1)
                 packages.append(fragment.replace(os.sep, '.'))
     return packages
 
-v = open(os.path.join(os.path.dirname(__file__), 'lib', 'sqlalchemy',
-         '__init__.py'))
+v = open(os.path.join(os.path.dirname(__file__), 
+                        'lib', 'sqlalchemy', '__init__.py'))
 VERSION = re.compile(r".*__version__ = '(.*?)'",
                      re.S).match(v.read()).group(1)
 v.close()
           packages=find_packages('lib'),
           package_dir={'': 'lib'},
           license="MIT License",
-          cmdclass={'build_ext': ve_build_ext},
+          cmdclass=cmdclass,
 
           tests_require=['nose >= 0.11'],
           test_suite="sqla_nose",
             **kwargs
           )
 
-try:
-    # Likely don't want the cextension built on PyPy+CPyExt
-    run_setup(not (pypy or py3k))
-except BuildFailed, exc:
-    print '*' * 75
-    print exc.cause
-    BUILD_EXT_WARNING = "WARNING: The C extension could not be compiled, speedups are not enabled."
-    print '*' * 75
-    print BUILD_EXT_WARNING
-    print "Failure information, if any, is above."
-    print "Retrying the build without the C extension now."
-    print '*' * 75
+if pypy or py3k:
+    run_setup(False)
+    status_msgs(
+        "WARNING: C extensions are not supported on " +
+            "this Python platform, speedups are not enabled.",
+        "Plain-Python build succeeded."
+    )
+else:
+    try:
+        run_setup(True)
+    except BuildFailed:
+        exc = sys.exc_info()[1] # work around py 2/3 different syntax
+        status_msgs(
+            exc.cause,
+            "WARNING: The C extension could not be compiled, " +
+                "speedups are not enabled.",
+            "Failure information, if any, is above.",
+            "Retrying the build without the C extension now."
+        )
 
-    run_setup(False)
+        run_setup(False)
 
-    print '*' * 75
-    print BUILD_EXT_WARNING
-    print "Plain-Python installation succeeded."
-    print '*' * 75
+        status_msgs(
+            "WARNING: The C extension could not be compiled, " +
+                "speedups are not enabled.",
+            "Plain-Python build succeeded."
+        )