Ticket #1696: make-some-RPMs-1696.patch

File make-some-RPMs-1696.patch, 19.6 KB (added by TimAllen, 10 years ago)

Address (some of) Glyph's review comments.

  • new file MANIFEST.in

    diff --git a/MANIFEST.in b/MANIFEST.in
    new file mode 100644
    index 0000000..2b207bf
    - +  
     1exclude rpm-post-install
     2exclude bin/admin/*
     3
     4# Include TwistedCore's extension-definitions in the sdist package, so they'll
     5# be available for bdist_rpm to read.
     6include twisted/topfiles/setup.py
     7
     8# Files that unit-tests assume are present. This list generated with the
     9# following command in the root of a fresh checkout:
     10#
     11#   find twisted -wholename '*/test/*' | grep -v '.py$'
     12#
     13include twisted/test/raiser.c
     14include twisted/test/raiser.pyx
     15include twisted/test/server.pem
     16include twisted/mail/test/rfc822.message
     17include twisted/trial/test/notpython
     18include twisted/lore/test/lore_index_file_out.html
     19include twisted/lore/test/lore_index_test.xhtml
     20include twisted/lore/test/lore_numbering_test_out2.html
     21include twisted/lore/test/lore_index_file_out_multiple.html
     22include twisted/lore/test/lore_index_test2.xhtml
     23include twisted/lore/test/simple3.html
     24include twisted/lore/test/lore_numbering_test_out.html
     25include twisted/lore/test/simple.html
     26include twisted/lore/test/simple4.html
     27include twisted/lore/test/lore_index_file_unnumbered_out.html
     28include twisted/lore/test/template.tpl
     29include twisted/web2/test/server.pem
     30include twisted/web2/test/stream_data.txt
     31
     32# Files required to be present at runtime:
     33include twisted/lore/template.mgp
     34include twisted/lore/xhtml1-strict.dtd
     35include twisted/lore/xhtml1-transitional.dtd
     36include twisted/lore/xhtml-lat1.ent
     37include twisted/lore/xhtml-special.ent
     38include twisted/lore/xhtml-symbol.ent
  • new file admin/rpm-post-install

    diff --git a/admin/rpm-post-install b/admin/rpm-post-install
    new file mode 100644
    index 0000000..45ea373
    - +  
     1#!/bin/sh
     2#
     3#  Create cache files.
     4
     5python -c 'from twisted.plugin import IPlugin, getPlugins; list(getPlugins(IPlugin))'
  • deleted file dmin/twisted.spec

    diff --git a/admin/twisted.spec b/admin/twisted.spec
    deleted file mode 100644
    index ef0f21e..0000000
    + -  
    1 %define name     Twisted
    2 %define version  SVN-trunk
    3 %define release  1tummy
    4 %define prefix   %{_prefix}
    5 %define py_libver 2.3
    6 
    7 Summary:        Twisted is an event-based framework for internet applications.
    8 Name:           %{name}
    9 Version:        %{version}
    10 Release:        %{release}
    11 Source:         %{name}-%{version}.tar.bz2
    12 License:        MIT
    13 Group:          System/Libraries
    14 URL:            http://www.twistedmatrix.com/
    15 Requires:       python >= %{py_libver}
    16 BuildRequires:  python-devel
    17 BuildRoot:      %{_tmppath}/%{name}-buildroot
    18 Prefix:         %{_prefix}
    19 
    20 %description
    21 Twisted is an event-based framework for internet applications.  It includes a
    22 web server, a telnet server, a chat server, a news server, a generic client
    23 and server for remote object access, and APIs for creating new protocols and
    24 services. Twisted supports integration of the Tk, GTK+, Qt or wxPython event
    25 loop with its main event loop. The Win32 event loop is also supported, as is
    26 basic support for running servers on top of Jython.
    27 
    28 %package doc
    29 Summary: Twisted documentation and example programs
    30 Group: Development/Python
    31 %description doc
    32 Twisted is an event-based framework for internet applications.
    33 Install Twisted-doc if you need the API documentation and example programs.
    34 
    35 %prep
    36 %setup -n %{name}-%{version}
    37 %build
    38 
    39 %install
    40 [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"
    41 mkdir -p "$RPM_BUILD_ROOT"
    42 
    43 python setup.py install --optimize=2 --record=installed-files \
    44       --root="$RPM_BUILD_ROOT"
    45 
    46 #  install man pages
    47 mkdir -p "$RPM_BUILD_ROOT"/%{_mandir}/man1/
    48 cp -a doc/man/*.1 "$RPM_BUILD_ROOT"/%{_mandir}/man1/
    49 
    50 %clean
    51 [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"
    52 
    53 %files
    54 %defattr(755,root,root)
    55 %doc CREDITS LICENSE README
    56 %{_bindir}/*
    57 %attr(644,-,-) %{_mandir}/man1/*
    58 %{_libdir}/python%{py_libver}/site-packages/twisted/
    59 
    60 %files doc
    61 %defattr(-,root,root)
    62 %doc doc/*
  • new file setup.cfg

    diff --git a/setup.cfg b/setup.cfg
    new file mode 100644
    index 0000000..d58dafe
    - +  
     1[bdist_rpm]
     2post-install = admin/rpm-post-install
     3
     4# Some RPM-based distributions configure RPM to automatically create .pyo files
     5# when .py files are installed, but don't configure bdist_rpm to add .pyo files
     6# to the list-of-files-to-be-installed. Since RPM will exit with an error if
     7# files are installed that aren't in the list-of-files-to-be-installed, this
     8# prevents bdist_rpm from working. This has been a problem for a very long time
     9# (at least since Fedora 6, if not before), but is due to be fixed in Fedora
     10# 11, with the same workaround we present here. For more details, see the
     11# upstream Fedora bug:
     12#
     13#   https://bugzilla.redhat.com/show_bug.cgi?id=236535
     14#
     15[install]
     16optimize = 1
  • setup.py

    diff --git a/setup.py b/setup.py
    index c8b5877..62a2743 100755
    a b def main(args): 
    4343    if os.path.exists('twisted'):
    4444        sys.path.insert(0, '.')
    4545    from twisted import copyright
    46     from twisted.python.dist import getDataFiles, getScripts, getPackages, setup
     46    from twisted.python.dist import getDataFiles, getScripts, getPackages, \
     47        getOptions, setup
    4748
    4849    # "" is included because core scripts are directly in bin/
    4950    projects = [''] + [x for x in os.listdir('bin')
    on event-based network programming and multiprotocol integration. 
    7374            conditionalExtensions = getExtensions(),
    7475            scripts = scripts,
    7576            data_files=getDataFiles('twisted'),
     77            options = getOptions(),
    7678            )
    7779
    7880    if 'setuptools' in sys.modules:
  • twisted/python/dist.py

    diff --git a/twisted/python/dist.py b/twisted/python/dist.py
    index 5727065..ac1e513 100644
    a b def getVersion(proj, base="twisted"): 
    120120    return ns['version'].base()
    121121
    122122
     123
     124def getOptions():
     125    """
     126    Return default options for the given project.
     127    """
     128    return {
     129            'bdist_rpm': {
     130                'requires': [
     131                    'python >= 2.3',
     132                    'python-zope-interface >= 3.0.1',
     133                ],
     134            },
     135        }
     136
     137
     138
    123139# Names that are exluded from globbing results:
    124140EXCLUDE_NAMES = ["{arch}", "CVS", ".cvsignore", "_darcs",
    125141                 "RCS", "SCCS", ".svn"]
  • twisted/python/test/test_dist.py

    diff --git a/twisted/python/test/test_dist.py b/twisted/python/test/test_dist.py
    index c69717d..98509b7 100644
    a b class GetScriptsTest(TestCase): 
    171171        os.mkdir(basedir)
    172172        scripts = dist.getScripts('noscripts', basedir=basedir)
    173173        self.assertEquals(scripts, [])
     174
     175
     176
     177class GetOptionsTest(TestCase):
     178
     179
     180    def test_getOptions_for_RPMs(self):
     181        """
     182        Test that getOptions returns appropriate options for RPM building.
     183        """
     184        options = dist.getOptions()
     185
     186        # We should have options for RPM building.
     187        self.failUnlessIn("bdist_rpm", options)
     188        rpm_options = options["bdist_rpm"]
     189
     190        # We should have configured requirements for installed RPMs.
     191        self.failUnlessIn("requires", rpm_options)
     192        requirements = rpm_options["requires"]
     193
     194        # We should require Python to be installed.
     195        python_reqs = [True for requirement in requirements if
     196                # The extra space ensures requirements like "python-foo" won't
     197                # produce false positives.
     198                requirement.startswith("python ")]
     199        self.failUnless(len(python_reqs) > 0, "Twisted RPMs should depend on "
     200                "Python.")
     201
     202        # We should require zope-interface to be installed.
     203        zi_reqs = [True for requirement in requirements if
     204                requirement.startswith("python-zope-interface")]
     205        self.failUnless(len(zi_reqs) > 0, "Twisted RPMs should depend on "
     206                "python-zope-interface.")
  • deleted file twisted/test/generator_failure_tests.py

    diff --git a/twisted/test/generator_failure_tests.py b/twisted/test/generator_failure_tests.py
    deleted file mode 100644
    index 8c31c27..0000000
    + -  
    1 # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
    2 # See LICENSE for details.
    3 
    4 
    5 """
    6 Python 2.5 test cases for failures thrown into generators.
    7 """
    8 
    9 import sys
    10 import traceback
    11 
    12 from twisted.trial.unittest import TestCase
    13 
    14 from twisted.python.failure import Failure
    15 from twisted.test.test_failure import getDivisionFailure
    16 from twisted.internet import defer
    17 
    18 
    19 class TwoPointFiveFailureTests(TestCase):
    20 
    21     def test_inlineCallbacksTracebacks(self):
    22         """
    23         inlineCallbacks that re-raise tracebacks into their deferred
    24         should not lose their tracebacsk.
    25         """
    26         f = getDivisionFailure()
    27         d = defer.Deferred()
    28         try:
    29             f.raiseException()
    30         except:
    31             d.errback()
    32 
    33         failures = []
    34         def collect_error(result):
    35             failures.append(result)
    36 
    37         def ic(d):
    38             yield d
    39         ic = defer.inlineCallbacks(ic)
    40         ic(d).addErrback(collect_error)
    41 
    42         newFailure, = failures
    43         self.assertEquals(
    44             traceback.extract_tb(newFailure.getTracebackObject())[-1][-1],
    45             "1/0"
    46         )
    47 
    48 
    49     def _throwIntoGenerator(self, f, g):
    50         try:
    51             f.throwExceptionIntoGenerator(g)
    52         except StopIteration:
    53             pass
    54         else:
    55             self.fail("throwExceptionIntoGenerator should have raised "
    56                       "StopIteration")
    57 
    58     def test_throwExceptionIntoGenerator(self):
    59         """
    60         It should be possible to throw the exception that a Failure
    61         represents into a generator.
    62         """
    63         stuff = []
    64         def generator():
    65             try:
    66                 yield
    67             except:
    68                 stuff.append(sys.exc_info())
    69             else:
    70                 self.fail("Yield should have yielded exception.")
    71         g = generator()
    72         f = getDivisionFailure()
    73         g.next()
    74         self._throwIntoGenerator(f, g)
    75 
    76         self.assertEquals(stuff[0][0], ZeroDivisionError)
    77         self.assertTrue(isinstance(stuff[0][1], ZeroDivisionError))
    78 
    79         self.assertEquals(traceback.extract_tb(stuff[0][2])[-1][-1], "1/0")
    80 
    81 
    82     def test_findFailureInGenerator(self):
    83         """
    84         Within an exception handler, it should be possible to find the
    85         original Failure that caused the current exception (if it was
    86         caused by throwExceptionIntoGenerator).
    87         """
    88         f = getDivisionFailure()
    89         f.cleanFailure()
    90 
    91         foundFailures = []
    92         def generator():
    93             try:
    94                 yield
    95             except:
    96                 foundFailures.append(Failure._findFailure())
    97             else:
    98                 self.fail("No exception sent to generator")
    99 
    100         g = generator()
    101         g.next()
    102         self._throwIntoGenerator(f, g)
    103 
    104         self.assertEqual(foundFailures, [f])
    105 
    106 
    107     def test_failureConstructionFindsOriginalFailure(self):
    108         """
    109         When a Failure is constructed in the context of an exception
    110         handler that is handling an exception raised by
    111         throwExceptionIntoGenerator, the new Failure should be chained to that
    112         original Failure.
    113         """
    114         f = getDivisionFailure()
    115         f.cleanFailure()
    116 
    117         newFailures = []
    118 
    119         def generator():
    120             try:
    121                 yield
    122             except:
    123                 newFailures.append(Failure())
    124             else:
    125                 self.fail("No exception sent to generator")
    126         g = generator()
    127         g.next()
    128         self._throwIntoGenerator(f, g)
    129 
    130         self.assertEqual(len(newFailures), 1)
    131         self.assertEqual(newFailures[0].getTraceback(), f.getTraceback())
    132 
    133     def test_ambiguousFailureInGenerator(self):
    134         """
    135         When a generator reraises a different exception,
    136         L{Failure._findFailure} inside the generator should find the reraised
    137         exception rather than original one.
    138         """
    139         def generator():
    140             try:
    141                 try:
    142                     yield
    143                 except:
    144                     [][1]
    145             except:
    146                 self.assertIsInstance(Failure().value, IndexError)
    147         g = generator()
    148         g.next()
    149         f = getDivisionFailure()
    150         self._throwIntoGenerator(f, g)
    151 
    152     def test_ambiguousFailureFromGenerator(self):
    153         """
    154         When a generator reraises a different exception,
    155         L{Failure._findFailure} above the generator should find the reraised
    156         exception rather than original one.
    157         """
    158         def generator():
    159             try:
    160                 yield
    161             except:
    162                 [][1]
    163         g = generator()
    164         g.next()
    165         f = getDivisionFailure()
    166         try:
    167             self._throwIntoGenerator(f, g)
    168         except:
    169             self.assertIsInstance(Failure().value, IndexError)
  • new file twisted/test/test_compile.py

    diff --git a/twisted/test/test_compile.py b/twisted/test/test_compile.py
    new file mode 100644
    index 0000000..05cc6ed
    - +  
     1
     2# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
     3# See LICENSE for details.
     4
     5
     6import compileall
     7from os.path import dirname
     8from twisted.trial import unittest
     9
     10
     11
     12class TestByteCompilation(unittest.TestCase):
     13
     14
     15    def test_twisted_can_be_bytecompiled(self):
     16        """
     17        Test that all the Twisted Python files can be byte-compiled.
     18
     19        Twisted should support "setup.py bdist_rpm" with every supported
     20        version of Python. Because the RPM building process byte-compiles all
     21        the Python files it can find, not just the ones referenced by import
     22        statements, we need a test that will ensure buildbots running old
     23        versions of Python will not overlook incompatible Python code.
     24        """
     25        import twisted
     26        self.failUnless(compileall.compile_dir(dirname(twisted.__file__),
     27            force=False, quiet=True), "Compilation failed")
  • twisted/test/test_failure.py

    diff --git a/twisted/test/test_failure.py b/twisted/test/test_failure.py
    index 7dc0ab1..29bcab0 100644
    a b class TestFormattableTraceback(unittest.TestCase): 
    314314                          ('filename.py', 235, 'method2', None)])
    315315
    316316
    317 if sys.version_info[:2] >= (2, 5):
    318     from twisted.test.generator_failure_tests import TwoPointFiveFailureTests
     317
     318class GeneratorFailureTestCase(unittest.TestCase):
     319    """
     320    Python 2.5 test cases for failures thrown into generators.
     321    """
     322
     323
     324    if sys.version_info[0] <= 2 and sys.version_info[1] <= 4:
     325        # Running these tests will raise all kinds of errors on versions before
     326        # 2.5, so skip the whole lot. Note that examples of syntax introduce in
     327        # 2.5 have to be wrapped in exec so that this file doesn't cause Python
     328        # 2.4 to die with a SyntaxError when it tries to parse the file.
     329        skip = "generator_failure_tests require Python 2.5"
     330
     331    def test_inlineCallbacksTracebacks(self):
     332        """
     333        inlineCallbacks that re-raise tracebacks into their deferred
     334        should not lose their tracebacsk.
     335        """
     336        f = getDivisionFailure()
     337        d = defer.Deferred()
     338        try:
     339            f.raiseException()
     340        except:
     341            d.errback()
     342
     343        failures = []
     344        def collect_error(result):
     345            failures.append(result)
     346
     347        def ic(d):
     348            yield d
     349        ic = defer.inlineCallbacks(ic)
     350        ic(d).addErrback(collect_error)
     351
     352        newFailure, = failures
     353        self.assertEquals(
     354            traceback.extract_tb(newFailure.getTracebackObject())[-1][-1],
     355            "1/0"
     356        )
     357
     358
     359    def _throwIntoGenerator(self, f, g):
     360        try:
     361            f.throwExceptionIntoGenerator(g)
     362        except StopIteration:
     363            pass
     364        else:
     365            self.fail("throwExceptionIntoGenerator should have raised "
     366                      "StopIteration")
     367
     368    def test_throwExceptionIntoGenerator(self):
     369        """
     370        It should be possible to throw the exception that a Failure
     371        represents into a generator.
     372        """
     373        stuff = []
     374        exec """
     375            def generator():
     376                try:
     377                    yield
     378                except:
     379                    stuff.append(sys.exc_info())
     380                else:
     381                    self.fail("Yield should have yielded exception.")
     382            """
     383        g = generator()
     384        f = getDivisionFailure()
     385        g.next()
     386        self._throwIntoGenerator(f, g)
     387
     388        self.assertEquals(stuff[0][0], ZeroDivisionError)
     389        self.assertTrue(isinstance(stuff[0][1], ZeroDivisionError))
     390
     391        self.assertEquals(traceback.extract_tb(stuff[0][2])[-1][-1], "1/0")
     392
     393
     394    def test_findFailureInGenerator(self):
     395        """
     396        Within an exception handler, it should be possible to find the
     397        original Failure that caused the current exception (if it was
     398        caused by throwExceptionIntoGenerator).
     399        """
     400        f = getDivisionFailure()
     401        f.cleanFailure()
     402
     403        foundFailures = []
     404        exec """
     405            def generator():
     406                try:
     407                    yield
     408                except:
     409                    foundFailures.append(Failure._findFailure())
     410                else:
     411                    self.fail("No exception sent to generator")
     412            """
     413
     414        g = generator()
     415        g.next()
     416        self._throwIntoGenerator(f, g)
     417
     418        self.assertEqual(foundFailures, [f])
     419
     420
     421    def test_failureConstructionFindsOriginalFailure(self):
     422        """
     423        When a Failure is constructed in the context of an exception
     424        handler that is handling an exception raised by
     425        throwExceptionIntoGenerator, the new Failure should be chained to that
     426        original Failure.
     427        """
     428        f = getDivisionFailure()
     429        f.cleanFailure()
     430
     431        newFailures = []
     432
     433        exec """
     434            def generator():
     435                try:
     436                    yield
     437                except:
     438                    newFailures.append(Failure())
     439                else:
     440                    self.fail("No exception sent to generator")
     441            """
     442        g = generator()
     443        g.next()
     444        self._throwIntoGenerator(f, g)
     445
     446        self.assertEqual(len(newFailures), 1)
     447        self.assertEqual(newFailures[0].getTraceback(), f.getTraceback())
     448
     449    def test_ambiguousFailureInGenerator(self):
     450        """
     451        When a generator reraises a different exception,
     452        L{Failure._findFailure} inside the generator should find the reraised
     453        exception rather than original one.
     454        """
     455        exec """
     456            def generator():
     457                try:
     458                    try:
     459                        yield
     460                    except:
     461                        [][1]
     462                except:
     463                    self.assertIsInstance(Failure().value, IndexError)
     464            """
     465        g = generator()
     466        g.next()
     467        f = getDivisionFailure()
     468        self._throwIntoGenerator(f, g)
     469
     470    def test_ambiguousFailureFromGenerator(self):
     471        """
     472        When a generator reraises a different exception,
     473        L{Failure._findFailure} above the generator should find the reraised
     474        exception rather than original one.
     475        """
     476        exec """
     477            def generator():
     478                try:
     479                    yield
     480                except:
     481                    [][1]
     482            """
     483        g = generator()
     484        g.next()
     485        f = getDivisionFailure()
     486        try:
     487            self._throwIntoGenerator(f, g)
     488        except:
     489            self.assertIsInstance(Failure().value, IndexError)