aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsetup.py12
-rwxr-xr-xsetuptools.egg-info/entry_points.txt13
-rwxr-xr-xsetuptools.txt136
-rw-r--r--setuptools/__init__.py22
-rwxr-xr-xsetuptools/command/egg_info.py14
-rw-r--r--setuptools/dist.py296
-rw-r--r--setuptools/extension.py10
7 files changed, 356 insertions, 147 deletions
diff --git a/setup.py b/setup.py
index 7302f710..e56e15f9 100755
--- a/setup.py
+++ b/setup.py
@@ -46,8 +46,18 @@ setup(
"%(cmd)s = setuptools.command.%(cmd)s:%(cmd)s" % locals()
for cmd in SETUP_COMMANDS if cmd!="build_py" or sys.version<"2.4"
],
+ "distutils.setup_keywords": [
+ "eager_resources = setuptools.dist:assert_string_list",
+ "namespace_packages = setuptools.dist:check_nsp",
+ "extras_require = setuptools.dist:check_extras",
+ "entry_points = setuptools.dist:check_entry_points",
+ "test_suite = setuptools.dist:check_test_suite",
+ "zip_safe = setuptools.dist:assert_bool",
+ ]
},
+ setup_requires = ['setuptools>=0.6a0'],
+
classifiers = [f.strip() for f in """
Development Status :: 3 - Alpha
Intended Audience :: Developers
@@ -78,5 +88,3 @@ setup(
-
-
diff --git a/setuptools.egg-info/entry_points.txt b/setuptools.egg-info/entry_points.txt
index 8baf6137..def14fac 100755
--- a/setuptools.egg-info/entry_points.txt
+++ b/setuptools.egg-info/entry_points.txt
@@ -1,13 +1,22 @@
+[distutils.setup_keywords]
+entry_points = setuptools.dist:check_entry_points
+extras_require = setuptools.dist:check_extras
+namespace_packages = setuptools.dist:check_nsp
+test_suite = setuptools.dist:check_test_suite
+eager_resources = setuptools.dist:assert_string_list
+zip_safe = setuptools.dist:assert_bool
+
[distutils.commands]
rotate = setuptools.command.rotate:rotate
develop = setuptools.command.develop:develop
setopt = setuptools.command.setopt:setopt
+build_py = setuptools.command.build_py:build_py
saveopts = setuptools.command.saveopts:saveopts
egg_info = setuptools.command.egg_info:egg_info
-depends = setuptools.command.depends:depends
+easy_install = setuptools.command.easy_install:easy_install
upload = setuptools.command.upload:upload
alias = setuptools.command.alias:alias
-easy_install = setuptools.command.easy_install:easy_install
+depends = setuptools.command.depends:depends
bdist_egg = setuptools.command.bdist_egg:bdist_egg
install = setuptools.command.install:install
test = setuptools.command.test:test
diff --git a/setuptools.txt b/setuptools.txt
index 2bd40905..7f9c8551 100755
--- a/setuptools.txt
+++ b/setuptools.txt
@@ -64,7 +64,11 @@ Installing ``setuptools``
=========================
Download `ez_setup.py`_ and run it; this will download and install the
-appropriate egg for your Python version.
+appropriate egg for your Python version. (Note: if you are behind
+an NTLM-based firewall that prevents Python programs from accessing the net
+directly, you may wish to install and use the `APS proxy server
+<http://ntlmaps.sf.net/>`_, which lets you get past such firewalls in the same
+way that your web browser(s) do.)
.. _ez_setup.py: `bootstrap module`_
@@ -80,6 +84,16 @@ To get the in-development version of setuptools, run::
You can then install it using the usual "setup.py install" incantation.
+Note that ``setuptools`` *must* be installed as an egg directory; it will not
+operate correctly otherwise. If you are unable to install to a valid
+``site-packages`` directory (e.g. a "non-root install"), you will therefore
+need to manually add the setuptools egg to your ``PYTHONPATH``. (You won't
+need to do this for every egg you install, because the ``pkg_resources`` module
+can automatically find eggs and add them to ``sys.path`` at runtime. It's just
+that the ``setuptools`` egg contains ``pkg_resources`` and therefore has to
+be manually bootstrapped if you can't install it to a ``site-packages``
+directory.)
+
Basic Use
=========
@@ -175,6 +189,15 @@ unless you need the associated ``setuptools`` feature.
installed to support those features. See the section below on `Declaring
Dependencies`_ for details and examples of the format of this argument.
+``setup_requires``
+ A string or list of strings specifying what other distributions need to
+ be present in order for the *setup script* to run. ``setuptools`` will
+ attempt to obtain these (even going so far as to download them using
+ ``EasyInstall``) before processing the rest of the setup script or commands.
+ This argument is needed if you are using distutils extensions as part of
+ your build process; for example, extensions that process setup() arguments
+ and turn them into EGG-INFO metadata files.
+
``namespace_packages``
A list of strings naming the project's "namespace packages". A namespace
package is a package that may be split across multiple project
@@ -1517,19 +1540,28 @@ The ``upload`` command has a few options worth noting:
Extending and Reusing ``setuptools``
------------------------------------
-Sorry, this section isn't written yet, and neither is a lot of what's below
-this point, except for the change log. You might want to `subscribe to changes
-in this page <setuptools?action=subscribe>`_ to see when new documentation is
-added or updated.
+Creating ``distutils`` Extensions
+=================================
+
+It can be hard to add new commands or setup arguments to the distutils. But
+the ``setuptools`` package makes it a bit easier, by allowing you to distribute
+a distutils extension as a separate project, and then have projects that need
+the extension just refer to it in their ``setup_requires`` argument.
+
+With ``setuptools``, your distutils extension projects can hook in new
+commands and ``setup()`` arguments just by defining "entry points". These
+are mappings from command or argument names to a specification of where to
+import a handler from. (See the section on `Dynamic Discovery of Services and
+Plugins`_ above for some more background on entry points.)
Adding Commands
-===============
+---------------
-You can create add-on packages that extend setuptools with additional commands
-by defining entry points in the ``distutils.commands`` group. For example, if
-you wanted to add a ``foo`` command, you might add something like this to your
-setup script::
+You can add new ``setup`` commands by defining entry points in the
+``distutils.commands`` group. For example, if you wanted to add a ``foo``
+command, you might add something like this to your distutils extension
+project's setup script::
setup(
# ...
@@ -1540,8 +1572,8 @@ setup script::
},
)
-Assuming, of course, that the ``foo`` class in ``mypackage.some_module`` is
-a ``setuptools.Command`` subclass.
+(Assuming, of course, that the ``foo`` class in ``mypackage.some_module`` is
+a ``setuptools.Command`` subclass.)
Once a project containing such entry points has been activated on ``sys.path``,
(e.g. by running "install" or "develop" with a site-packages installation
@@ -1550,18 +1582,76 @@ scripts. It is not necessary to use the ``--command-packages`` option or
to monkeypatch the ``distutils.command`` package to install your commands;
``setuptools`` automatically adds a wrapper to the distutils to search for
entry points in the active distributions on ``sys.path``. In fact, this is
-how setuptools' own commands are installed: the setuptools setup script defines
-entry points for them.
+how setuptools' own commands are installed: the setuptools project's setup
+script defines entry points for them!
+
+
+Adding ``setup()`` Arguments
+----------------------------
+
+Sometimes, your commands may need additional arguments to the ``setup()``
+script. You can enable this by defining entry points in the
+``distutils.setup_keywords`` group. For example, if you wanted a ``setup()``
+argument called ``bar_baz``, you might add something like this to your
+distutils extension project's setup script::
+
+ setup(
+ # ...
+ entry_points = {
+ "distutils.commands": [
+ "foo = mypackage.some_module:foo",
+ ],
+ "distutils.setup_keywords": [
+ "bar_baz = mypackage.some_module:validate_bar_baz",
+ ],
+ },
+ )
+
+The idea here is that the entry point defines a function that will be called
+to validate the ``setup()`` argument, if it's supplied. The ``Distribution``
+object will have the initial value of the attribute set to ``None``, and the
+validation function will only be called if the ``setup()`` call sets it to
+a non-None value. Here's an example validation function::
+
+ def assert_bool(dist, attr, value):
+ """Verify that value is True, False, 0, or 1"""
+ if bool(value) != value:
+ raise DistutilsSetupError(
+ "%r must be a boolean value (got %r)" % (attr,value)
+ )
+
+Your function should accept three arguments: the ``Distribution`` object,
+the attribute name, and the attribute value. It should raise a
+``DistutilsSetupError`` (from the ``distutils.error`` module) if the argument
+is invalid. Remember, your function will only be called with non-None values,
+and the default value of arguments defined this way is always None. So, your
+commands should always be prepared for the possibility that the attribute will
+be ``None`` when they access it later.
+
+If more than one active distribution defines an entry point for the same
+``setup()`` argument, *all* of them will be called. This allows multiple
+distutils extensions to define a common argument, as long as they agree on
+what values of that argument are valid.
+
+Also note that as with commands, it is not necessary to subclass or monkeypatch
+the distutils ``Distribution`` class in order to add your arguments; it is
+sufficient to define the entry points in your extension, as long as the setup
+script lists your extension in its ``setup_requires`` argument.
Subclassing ``Command``
-----------------------
+Sorry, this section isn't written yet, and neither is a lot of what's below
+this point, except for the change log. You might want to `subscribe to changes
+in this page <setuptools?action=subscribe>`_ to see when new documentation is
+added or updated.
+
XXX
-Utility Modules
-===============
+Reusing ``setuptools`` Code
+===========================
``ez_setup``
------------
@@ -1604,14 +1694,24 @@ Release Notes/Change History
* The ``sdist`` command now recognizes Subversion "deleted file" entries and
does not include them in source distributions.
-
+
+ * ``setuptools`` now embeds itself more thoroughly into the distutils, so that
+ other distutils extensions (e.g. py2exe, py2app) will subclass setuptools'
+ versions of things, rather than the native distutils ones.
+
* Fixed some problems using ``pkg_resources`` w/PEP 302 loaders other than
``zipimport``, and the previously-broken "eager resource" support.
* Fixed ``pkg_resources.resource_exists()`` not working correctly, along with
some other resource API bugs.
- * Added ``entry_points`` argument to ``setup()``
+ * Added ``entry_points`` and ``setup_requires`` arguments to ``setup()``;
+ ``setup_requires`` allows you to automatically find and download packages
+ that are needed in order to *build* your project (as opposed to running it).
+
+ * ``setuptools`` now finds its commands and ``setup()`` argument validators
+ using entry points, so that they are extensible by third-party packages.
+ See `Creating distutils Extensions`_ above for more details.
* Many ``pkg_resources`` API changes and enhancements:
diff --git a/setuptools/__init__.py b/setuptools/__init__.py
index 05c4a73e..eeb2975b 100644
--- a/setuptools/__init__.py
+++ b/setuptools/__init__.py
@@ -1,6 +1,6 @@
"""Extensions to the 'distutils' for large or complex distributions"""
+from setuptools.dist import Distribution, Feature, _get_unpatched
import distutils.core, setuptools.command
-from setuptools.dist import Distribution, Feature
from setuptools.extension import Extension
from setuptools.depends import Require
from distutils.core import Command as _Command
@@ -39,17 +39,9 @@ def find_packages(where='.', exclude=()):
out = [item for item in out if not fnmatchcase(item,pat)]
return out
-def setup(**attrs):
- """Do package setup
-
- This function takes the same arguments as 'distutils.core.setup()', except
- that the default distribution class is 'setuptools.dist.Distribution'. See
- that class' documentation for details on the new keyword arguments that it
- makes available via this function.
- """
- attrs.setdefault("distclass",Distribution)
- return distutils.core.setup(**attrs)
+setup = distutils.core.setup
+_Command = _get_unpatched(_Command)
class Command(_Command):
__doc__ = _Command.__doc__
@@ -68,6 +60,14 @@ class Command(_Command):
setattr(cmd,k,v) # update command with keywords
return cmd
+import distutils.core
+distutils.core.Command = Command # we can't patch distutils.cmd, alas
+
+
+
+
+
+
diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py
index 8577230f..7d0a1473 100755
--- a/setuptools/command/egg_info.py
+++ b/setuptools/command/egg_info.py
@@ -9,7 +9,6 @@ from distutils.errors import *
from distutils import log
from pkg_resources import parse_requirements, safe_name, \
safe_version, yield_lines, EntryPoint
-from setuptools.dist import iter_distribution_names
class egg_info(Command):
@@ -39,6 +38,7 @@ class egg_info(Command):
+
def finalize_options (self):
self.egg_name = safe_name(self.distribution.get_name())
self.egg_version = self.tagged_version()
@@ -149,7 +149,7 @@ class egg_info(Command):
def write_toplevel_names(self):
pkgs = dict.fromkeys(
[k.split('.',1)[0]
- for k in iter_distribution_names(self.distribution)
+ for k in self.distribution.iter_distribution_names()
]
)
toplevel = os.path.join(self.egg_info, "top_level.txt")
@@ -164,12 +164,8 @@ class egg_info(Command):
def write_or_delete_dist_arg(self, argname, filename=None):
value = getattr(self.distribution, argname, None)
- if value is None:
- return
-
filename = filename or argname+'.txt'
filename = os.path.join(self.egg_info,filename)
-
if value:
log.info("writing %s", filename)
if not self.dry_run:
@@ -177,8 +173,12 @@ class egg_info(Command):
f.write('\n'.join(value))
f.write('\n')
f.close()
-
elif os.path.exists(filename):
+ if value is None:
+ log.warn(
+ "%s not set in setup(), but %s exists", argname, filename
+ )
+ return
log.info("deleting %s", filename)
if not self.dry_run:
os.unlink(filename)
diff --git a/setuptools/dist.py b/setuptools/dist.py
index 40234b4e..6d226d68 100644
--- a/setuptools/dist.py
+++ b/setuptools/dist.py
@@ -9,36 +9,118 @@ from setuptools.command.sdist import sdist
from setuptools.command.install_lib import install_lib
from distutils.errors import DistutilsOptionError, DistutilsPlatformError
from distutils.errors import DistutilsSetupError
-import setuptools, pkg_resources
-
-def get_command_class(self, command):
- """Pluggable version of get_command_class()"""
- if command in self.cmdclass:
- return self.cmdclass[command]
-
- for ep in pkg_resources.iter_entry_points('distutils.commands',command):
- self.cmdclass[command] = cmdclass = ep.load()
- return cmdclass
- else:
- return _old_get_command_class(self, command)
-
-def print_commands(self):
- for ep in pkg_resources.iter_entry_points('distutils.commands'):
- if ep.name not in self.cmdclass:
- cmdclass = ep.load(False) # don't require extras, we're not running
- self.cmdclass[ep.name] = cmdclass
- return _old_print_commands(self)
-
-for meth in 'print_commands', 'get_command_class':
- if getattr(_Distribution,meth).im_func.func_globals is not globals():
- globals()['_old_'+meth] = getattr(_Distribution,meth)
- setattr(_Distribution, meth, globals()[meth])
+import setuptools, pkg_resources, distutils.core, distutils.dist, distutils.cmd
+import os
+
+def _get_unpatched(cls):
+ """Protect against re-patching the distutils if reloaded
+
+ Also ensures that no other distutils extension monkeypatched the distutils
+ first.
+ """
+ while cls.__module__.startswith('setuptools'):
+ cls, = cls.__bases__
+ if not cls.__module__.startswith('distutils'):
+ raise AssertionError(
+ "distutils has already been patched by %r" % cls
+ )
+ return cls
+
+_Distribution = _get_unpatched(_Distribution)
sequence = tuple, list
+
+
+
+
+
+
+def assert_string_list(dist, attr, value):
+ """Verify that value is a string list or None"""
+ try:
+ assert ''.join(value)!=value
+ except (TypeError,ValueError,AttributeError,AssertionError):
+ raise DistutilsSetupError(
+ "%r must be a list of strings (got %r)" % (attr,value)
+ )
+
+def check_nsp(dist, attr, value):
+ """Verify that namespace packages are valid"""
+ assert_string_list(dist,attr,value)
+
+ for nsp in value:
+ for name in dist.iter_distribution_names():
+ if name.startswith(nsp+'.'): break
+ else:
+ raise DistutilsSetupError(
+ "Distribution contains no modules or packages for " +
+ "namespace package %r" % nsp
+ )
+
+def check_extras(dist, attr, value):
+ """Verify that extras_require mapping is valid"""
+ try:
+ for k,v in value.items():
+ list(pkg_resources.parse_requirements(v))
+ except (TypeError,ValueError,AttributeError):
+ raise DistutilsSetupError(
+ "'extras_require' must be a dictionary whose values are "
+ "strings or lists of strings containing valid project/version "
+ "requirement specifiers."
+ )
+
+def assert_bool(dist, attr, value):
+ """Verify that value is True, False, 0, or 1"""
+ if bool(value) != value:
+ raise DistutilsSetupError(
+ "%r must be a boolean value (got %r)" % (attr,value)
+ )
+
+def check_install_requires(dist, attr, value):
+ """Verify that install_requires is a valid requirements list"""
+ try:
+ list(pkg_resources.parse_requirements(value))
+ except (TypeError,ValueError):
+ raise DistutilsSetupError(
+ "'install_requires' must be a string or list of strings "
+ "containing valid project/version requirement specifiers"
+ )
+
+def check_entry_points(dist, attr, value):
+ """Verify that entry_points map is parseable"""
+ try:
+ pkg_resources.EntryPoint.parse_map(value)
+ except ValueError, e:
+ raise DistutilsSetupError(e)
+
+
+def check_test_suite(dist, attr, value):
+ if not isinstance(value,basestring):
+ raise DistutilsSetupError("test_suite must be a string")
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
class Distribution(_Distribution):
"""Distribution with support for features, tests, and package data
@@ -125,16 +207,19 @@ class Distribution(_Distribution):
have_package_data = hasattr(self, "package_data")
if not have_package_data:
self.package_data = {}
+
self.features = {}
- self.test_suite = None
self.requires = []
- self.install_requires = []
- self.extras_require = {}
self.dist_files = []
- self.zip_safe = None
- self.namespace_packages = None
- self.eager_resources = None
- self.entry_points = None
+
+ if attrs and 'setup_requires' in attrs:
+ # Make sure we have any eggs needed to interpret 'attrs'
+ self.fetch_build_eggs(attrs.pop('setup_requires'))
+
+ for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
+ if not hasattr(self,ep.name):
+ setattr(self,ep.name,None)
+
_Distribution.__init__(self,attrs)
@@ -145,20 +230,17 @@ class Distribution(_Distribution):
self._finalize_features()
return result
-
def _feature_attrname(self,name):
"""Convert feature name to corresponding option attribute name"""
return 'with_'+name.replace('-','_')
-
-
-
-
-
-
-
-
-
+ def fetch_build_eggs(self, requires):
+ """Resolve pre-setup requirements"""
+ from pkg_resources import working_set, parse_requirements
+ for dist in working_set.resolve(
+ parse_requirements(requires), installer=self.fetch_build_egg
+ ):
+ working_set.add(dist)
@@ -174,49 +256,34 @@ class Distribution(_Distribution):
"setuptools. Please remove it from your setup script."
)
- try:
- list(pkg_resources.parse_requirements(self.install_requires))
- except (TypeError,ValueError):
- raise DistutilsSetupError(
- "'install_requires' must be a string or list of strings "
- "containing valid project/version requirement specifiers"
- )
+ for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'):
+ value = getattr(self,ep.name,None)
+ if value is not None:
+ ep.require(installer=self.fetch_build_egg)
+ ep.load()(self, ep.name, value)
+
+ def fetch_build_egg(self, req):
+ """Fetch an egg needed for building"""
try:
- for k,v in self.extras_require.items():
- list(pkg_resources.parse_requirements(v))
- except (TypeError,ValueError,AttributeError):
- raise DistutilsSetupError(
- "'extras_require' must be a dictionary whose values are "
- "strings or lists of strings containing valid project/version "
- "requirement specifiers."
+ cmd = self._egg_fetcher
+ except AttributeError:
+ from setuptools.command.easy_install import easy_install
+ cmd = easy_install(
+ self.__class__({'script_args':['easy_install']}),
+ args="x", install_dir=os.curdir, exclude_scripts=True,
+ always_copy=False, build_directory=None, editable=False,
+ upgrade=False
)
+ cmd.ensure_finalized()
+ cmd.zip_ok = None # override any setup.cfg setting for these
+ cmd.build_directory = None
+ self._egg_fetcher = cmd
- for attr in 'namespace_packages','eager_resources':
- value = getattr(self,attr,None)
- if value is not None:
- try:
- assert ''.join(value)!=value
- except (TypeError,ValueError,AttributeError,AssertionError):
- raise DistutilsSetupError(
- "%r must be a list of strings (got %r)" % (attr,value)
- )
+ return cmd.easy_install(req)
- for nsp in self.namespace_packages or ():
- for name in iter_distribution_names(self):
- if name.startswith(nsp+'.'): break
- else:
- raise DistutilsSetupError(
- "Distribution contains no modules or packages for " +
- "namespace package %r" % nsp
- )
- if self.entry_points is not None:
- try:
- pkg_resources.EntryPoint.parse_map(self.entry_points)
- except ValueError, e:
- raise DistutilsSetupError(e)
def _set_global_opts_from_features(self):
"""Add --with-X/--without-X options based on optional features"""
@@ -244,22 +311,7 @@ class Distribution(_Distribution):
- def _finalize_features(self):
- """Add/remove features and resolve dependencies between them"""
-
- # First, flag all the enabled items (and thus their dependencies)
- for name,feature in self.features.items():
- enabled = self.feature_is_included(name)
- if enabled or (enabled is None and feature.include_by_default()):
- feature.include_in(self)
- self._set_feature(name,1)
- # Then disable the rest, so that off-by-default features don't
- # get flagged as errors when they're required by an enabled feature
- for name,feature in self.features.items():
- if not self.feature_is_included(name):
- feature.exclude_from(self)
- self._set_feature(name,0)
@@ -274,12 +326,42 @@ class Distribution(_Distribution):
+ def _finalize_features(self):
+ """Add/remove features and resolve dependencies between them"""
+ # First, flag all the enabled items (and thus their dependencies)
+ for name,feature in self.features.items():
+ enabled = self.feature_is_included(name)
+ if enabled or (enabled is None and feature.include_by_default()):
+ feature.include_in(self)
+ self._set_feature(name,1)
+ # Then disable the rest, so that off-by-default features don't
+ # get flagged as errors when they're required by an enabled feature
+ for name,feature in self.features.items():
+ if not self.feature_is_included(name):
+ feature.exclude_from(self)
+ self._set_feature(name,0)
+ def get_command_class(self, command):
+ """Pluggable version of get_command_class()"""
+ if command in self.cmdclass:
+ return self.cmdclass[command]
+ for ep in pkg_resources.iter_entry_points('distutils.commands',command):
+ ep.require(installer=self.fetch_build_egg)
+ self.cmdclass[command] = cmdclass = ep.load()
+ return cmdclass
+ else:
+ return _Distribution.get_command_class(self, command)
+ def print_commands(self):
+ for ep in pkg_resources.iter_entry_points('distutils.commands'):
+ if ep.name not in self.cmdclass:
+ cmdclass = ep.load(False) # don't require extras, we're not running
+ self.cmdclass[ep.name] = cmdclass
+ return _Distribution.print_commands(self)
@@ -572,25 +654,25 @@ class Distribution(_Distribution):
return d
-def iter_distribution_names(distribution):
- """Yield all packages, modules, and extensions declared by distribution"""
-
- for pkg in distribution.packages or ():
- yield pkg
-
- for module in distribution.py_modules or ():
- yield module
-
- for ext in distribution.ext_modules or ():
- if isinstance(ext,tuple):
- name,buildinfo = ext
- yield name
- else:
- yield ext.name
+ def iter_distribution_names(self):
+ """Yield all packages, modules, and extension names in distribution"""
+ for pkg in self.packages or ():
+ yield pkg
+ for module in self.py_modules or ():
+ yield module
+ for ext in self.ext_modules or ():
+ if isinstance(ext,tuple):
+ name,buildinfo = ext
+ yield name
+ else:
+ yield ext.name
+# Install it throughout the distutils
+for module in distutils.dist, distutils.core, distutils.cmd:
+ module.Distribution = Distribution
diff --git a/setuptools/extension.py b/setuptools/extension.py
index 55a4d946..37b62576 100644
--- a/setuptools/extension.py
+++ b/setuptools/extension.py
@@ -7,6 +7,9 @@ except ImportError:
# Pyrex isn't around, so fix up the sources
+ from dist import _get_unpatched
+ _Extension = _get_unpatched(_Extension)
+
class Extension(_Extension):
"""Extension that uses '.c' files in place of '.pyx' files"""
@@ -21,7 +24,14 @@ except ImportError:
sources.append(s)
self.sources = sources
+ import sys, distutils.core, distutils.extension
+ distutils.core.Extension = Extension
+ distutils.extension.Extension = Extension
+ if 'distutils.command.build_ext' in sys.modules:
+ sys.modules['distutils.command.build_ext'].Extension = Extension
+
else:
# Pyrex is here, just use regular extension type
Extension = _Extension
+