Clean and get setup.py working once and for all.
Fixes: README.rst now included Double line spacing removed from long_description Source package now includes tests, examples, etc using Manifest.in README.rst typos fixed Added README.rst section on installing dnspython for Python3 Version bumped to RC2 Version is now taken from sleekxmpp.version.__version__ without having to pull in the entire library Added 'test' command for setup.py Simplified testall.py Docs build cleanly from source package after installation
This commit is contained in:
parent
2a80824076
commit
ede59ab40e
8 changed files with 130 additions and 81 deletions
6
MANIFEST.in
Normal file
6
MANIFEST.in
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
include README.rst
|
||||||
|
include LICENSE
|
||||||
|
include testall.py
|
||||||
|
recursive-include docs Makefile *.bat *.py *.rst *.css *.ttf *.png
|
||||||
|
recursive-include examples *.py
|
||||||
|
recursive-include tests *.py
|
20
README.rst
20
README.rst
|
@ -34,7 +34,8 @@ SleekXMPP's design goals and philosphy are:
|
||||||
|
|
||||||
Get the Code
|
Get the Code
|
||||||
------------
|
------------
|
||||||
.. code-block:: sh
|
|
||||||
|
Get the latest stable version from PyPI::
|
||||||
|
|
||||||
pip install sleekxmpp
|
pip install sleekxmpp
|
||||||
|
|
||||||
|
@ -54,6 +55,15 @@ The latest source code for SleekXMPP may be found on `Github
|
||||||
**Develop Releases**
|
**Develop Releases**
|
||||||
- `Latest Develop Version <http://github.com/fritzy/SleekXMPP/zipball/develop>`_
|
- `Latest Develop Version <http://github.com/fritzy/SleekXMPP/zipball/develop>`_
|
||||||
|
|
||||||
|
Installing DNSPython
|
||||||
|
---------------------
|
||||||
|
If you are using Python3 and wish to use dnspython, you will have to checkout and
|
||||||
|
install the ``python3`` branch::
|
||||||
|
|
||||||
|
git clone http://github.com/rthalley/dnspython
|
||||||
|
cd dnspython
|
||||||
|
git checkout python3
|
||||||
|
python3 setup.py install
|
||||||
|
|
||||||
Discussion
|
Discussion
|
||||||
----------
|
----------
|
||||||
|
@ -68,7 +78,6 @@ help with SleekXMPP.
|
||||||
|
|
||||||
Documentation and Testing
|
Documentation and Testing
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Documentation can be found both inline in the code, and as a Sphinx project in ``/docs``.
|
Documentation can be found both inline in the code, and as a Sphinx project in ``/docs``.
|
||||||
To generate the Sphinx documentation, follow the commands below. The HTML output will
|
To generate the Sphinx documentation, follow the commands below. The HTML output will
|
||||||
be in ``docs/_build/html``::
|
be in ``docs/_build/html``::
|
||||||
|
@ -84,7 +93,6 @@ To run the test suite for SleekXMPP::
|
||||||
|
|
||||||
The SleekXMPP Boilerplate
|
The SleekXMPP Boilerplate
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Projects using SleekXMPP tend to follow a basic pattern for setting up client/component
|
Projects using SleekXMPP tend to follow a basic pattern for setting up client/component
|
||||||
connections and configuration. Here is the gist of the boilerplate needed for a SleekXMPP
|
connections and configuration. Here is the gist of the boilerplate needed for a SleekXMPP
|
||||||
based project. See the documetation or examples directory for more detailed archetypes for
|
based project. See the documetation or examples directory for more detailed archetypes for
|
||||||
|
@ -136,8 +144,10 @@ SleekXMPP projects::
|
||||||
xmpp.register_plugin('xep_0199') # XMPP Ping
|
xmpp.register_plugin('xep_0199') # XMPP Ping
|
||||||
|
|
||||||
# If you are working with an OpenFire server, you will need
|
# If you are working with an OpenFire server, you will need
|
||||||
# to useuterborg Larsson version:
|
# to use a different SSL version:
|
||||||
# xmppissl_version = ssl.PROTOCOL_SSLv3
|
#
|
||||||
|
# import ssl
|
||||||
|
# xmpp.ssl_version = ssl.PROTOCOL_SSLv3
|
||||||
|
|
||||||
if xmpp.connect():
|
if xmpp.connect():
|
||||||
xmpp.process(block=True)
|
xmpp.process(block=True)
|
||||||
|
|
|
@ -4,8 +4,6 @@ clientxmpp
|
||||||
|
|
||||||
.. module:: sleekxmpp.clientxmpp
|
.. module:: sleekxmpp.clientxmpp
|
||||||
|
|
||||||
.. autodata:: SRV_SUPPORT
|
|
||||||
|
|
||||||
.. autoclass:: ClientXMPP
|
.. autoclass:: ClientXMPP
|
||||||
|
|
||||||
.. automethod:: connect
|
.. automethod:: connect
|
||||||
|
|
21
setup.py
Normal file → Executable file
21
setup.py
Normal file → Executable file
|
@ -4,16 +4,15 @@
|
||||||
# Copyright (C) 2007-2011 Nathanael C. Fritz
|
# Copyright (C) 2007-2011 Nathanael C. Fritz
|
||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
#
|
#
|
||||||
# This software is licensed as described in the README file,
|
# This software is licensed as described in the README.rst and LICENSE
|
||||||
# which you should have received as part of this distribution.
|
# file, which you should have received as part of this distribution.
|
||||||
#
|
|
||||||
|
|
||||||
# from ez_setup import use_setuptools
|
|
||||||
from distutils.core import setup
|
|
||||||
import sys
|
import sys
|
||||||
|
from distutils.core import setup, Command
|
||||||
|
# from ez_setup import use_setuptools
|
||||||
|
|
||||||
import sleekxmpp
|
from testall import TestCommand
|
||||||
|
from sleekxmpp.version import __version__
|
||||||
# if 'cygwin' in sys.platform.lower():
|
# if 'cygwin' in sys.platform.lower():
|
||||||
# min_version = '0.6c6'
|
# min_version = '0.6c6'
|
||||||
# else:
|
# else:
|
||||||
|
@ -27,10 +26,10 @@ import sleekxmpp
|
||||||
#
|
#
|
||||||
# from setuptools import setup, find_packages, Extension, Feature
|
# from setuptools import setup, find_packages, Extension, Feature
|
||||||
|
|
||||||
VERSION = sleekxmpp.__version__
|
VERSION = __version__
|
||||||
DESCRIPTION = 'SleekXMPP is an elegant Python library for XMPP (aka Jabber, Google Talk, etc).'
|
DESCRIPTION = 'SleekXMPP is an elegant Python library for XMPP (aka Jabber, Google Talk, etc).'
|
||||||
with open('README.rst') as readme:
|
with open('README.rst') as readme:
|
||||||
LONG_DESCRIPTION = '\n'.join(readme)
|
LONG_DESCRIPTION = ''.join(readme)
|
||||||
|
|
||||||
CLASSIFIERS = [ 'Intended Audience :: Developers',
|
CLASSIFIERS = [ 'Intended Audience :: Developers',
|
||||||
'License :: OSI Approved :: MIT License',
|
'License :: OSI Approved :: MIT License',
|
||||||
|
@ -93,5 +92,7 @@ setup(
|
||||||
license = 'MIT',
|
license = 'MIT',
|
||||||
platforms = [ 'any' ],
|
platforms = [ 'any' ],
|
||||||
packages = packages,
|
packages = packages,
|
||||||
requires = [ 'tlslite', 'pythondns' ],
|
requires = [ 'dnspython' ],
|
||||||
|
classifiers = CLASSIFIERS,
|
||||||
|
cmdclass = {'test': TestCommand}
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,5 +15,4 @@ from sleekxmpp.xmlstream import XMLStream, RestartStream
|
||||||
from sleekxmpp.xmlstream.matcher import *
|
from sleekxmpp.xmlstream.matcher import *
|
||||||
from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET
|
from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET
|
||||||
|
|
||||||
__version__ = '1.0rc1'
|
from sleekxmpp.version import __version__, __version_info__
|
||||||
__version_info__ = (1, 0, 0, 'rc1', 0)
|
|
||||||
|
|
13
sleekxmpp/version.py
Normal file
13
sleekxmpp/version.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
"""
|
||||||
|
SleekXMPP: The Sleek XMPP Library
|
||||||
|
Copyright (C) 2010 Nathanael C. Fritz
|
||||||
|
This file is part of SleekXMPP.
|
||||||
|
|
||||||
|
See the file LICENSE for copying permission.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# We don't want to have to import the entire library
|
||||||
|
# just to get the version info for setup.py
|
||||||
|
|
||||||
|
__version__ = '1.0rc2'
|
||||||
|
__version_info__ = (1, 0, 0, 'rc2', 0)
|
117
testall.py
Normal file → Executable file
117
testall.py
Normal file → Executable file
|
@ -1,70 +1,63 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import unittest
|
|
||||||
import logging
|
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
import unittest
|
||||||
|
import distutils.core
|
||||||
|
|
||||||
class testoverall(unittest.TestCase):
|
from glob import glob
|
||||||
|
from os.path import splitext, basename, join as pjoin, walk
|
||||||
|
|
||||||
def testModules(self):
|
|
||||||
"""Testing all modules by compiling them"""
|
|
||||||
import compileall
|
|
||||||
import re
|
|
||||||
if sys.version_info < (3,0):
|
|
||||||
self.failUnless(compileall.compile_dir('.' + os.sep + 'sleekxmpp', rx=re.compile('/[.]svn'), quiet=True))
|
|
||||||
else:
|
|
||||||
self.failUnless(compileall.compile_dir('.' + os.sep + 'sleekxmpp', rx=re.compile('/[.]svn|.*26.*'), quiet=True))
|
|
||||||
|
|
||||||
def testTabNanny(self):
|
def run_tests():
|
||||||
"""Invoking the tabnanny"""
|
"""
|
||||||
import tabnanny
|
Find and run all tests in the tests/ directory.
|
||||||
self.failIf(tabnanny.check("." + os.sep + 'sleekxmpp'))
|
|
||||||
#raise "Help!"
|
Excludes live tests (tests/live_*).
|
||||||
|
"""
|
||||||
|
testfiles = ['tests.test_overall']
|
||||||
|
exclude = ['__init__.py', 'test_overall.py']
|
||||||
|
for t in glob(pjoin('.', 'tests', '*.py')):
|
||||||
|
if True not in [t.endswith(ex) for ex in exclude]:
|
||||||
|
if basename(t).startswith('test_'):
|
||||||
|
testfiles.append('tests.%s' % splitext(basename(t))[0])
|
||||||
|
|
||||||
|
suites = []
|
||||||
|
for file in testfiles:
|
||||||
|
__import__(file)
|
||||||
|
suites.append(sys.modules[file].suite)
|
||||||
|
|
||||||
|
tests = unittest.TestSuite(suites)
|
||||||
|
runner = unittest.TextTestRunner(verbosity=2)
|
||||||
|
|
||||||
|
# Disable logging output
|
||||||
|
logging.basicConfig(level=100)
|
||||||
|
logging.disable(100)
|
||||||
|
|
||||||
|
result = runner.run(tests)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# Add a 'test' command for setup.py
|
||||||
|
|
||||||
|
class TestCommand(distutils.core.Command):
|
||||||
|
|
||||||
|
user_options = [ ]
|
||||||
|
|
||||||
|
def initialize_options(self):
|
||||||
|
self._dir = os.getcwd()
|
||||||
|
|
||||||
|
def finalize_options(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
run_tests()
|
||||||
|
|
||||||
def disabled_testMethodLength(self):
|
|
||||||
"""Testing for excessive method lengths"""
|
|
||||||
import re
|
|
||||||
dirs = os.walk(sys.path[0] + os.sep + 'sleekxmpp')
|
|
||||||
offenders = []
|
|
||||||
for d in dirs:
|
|
||||||
if not '.svn' in d[0]:
|
|
||||||
for filename in d[2]:
|
|
||||||
if filename.endswith('.py') and d[0].find("template%stemplates" % os.sep) == -1:
|
|
||||||
with open("%s%s%s" % (d[0],os.sep,filename), "r") as fp:
|
|
||||||
cur = None
|
|
||||||
methodline = lineno = methodlen = methodindent = 0
|
|
||||||
for line in fp:
|
|
||||||
indentlevel = re.compile("^[\t ]*").search(line).end()
|
|
||||||
line = line.expandtabs()
|
|
||||||
lineno += 1
|
|
||||||
if line.strip().startswith("def ") or line.strip().startswith("except") or (line.strip() and methodindent > indentlevel) or (line.strip() and methodindent == indentlevel): #new method found or old one ended
|
|
||||||
if cur: #existing method needs final evaluation
|
|
||||||
if methodlen > 50 and not cur.strip().startswith("def setupUi"):
|
|
||||||
offenders.append("Method '%s' on line %s of %s/%s is longer than 50 lines (%s)" % (cur.strip(),methodline,d[0][len(rootp):],filename,methodlen))
|
|
||||||
methodlen = 0
|
|
||||||
cur = line
|
|
||||||
methodindent = indentlevel
|
|
||||||
methodline = lineno
|
|
||||||
if line and cur and not line.strip().startswith("#") and not (cur.strip().startswith("try:") and methodindent == 0): #if we weren't all whitespace and weren't a comment
|
|
||||||
methodlen += 1
|
|
||||||
self.failIf(offenders,"\n".join(offenders))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
logging.basicConfig(level=100)
|
result = run_tests()
|
||||||
logging.disable(100)
|
print("<tests %s ran='%s' errors='%s' fails='%s' success='%s' />" % (
|
||||||
#this doesn't need to be very clean
|
"xmlns='http//andyet.net/protocol/tests'",
|
||||||
alltests = [unittest.TestLoader().loadTestsFromTestCase(testoverall)]
|
result.testsRun, len(result.errors),
|
||||||
rootp = sys.path[0] + os.sep + 'tests'
|
len(result.failures), result.wasSuccessful()))
|
||||||
dirs = os.walk(rootp)
|
|
||||||
for d in dirs:
|
|
||||||
if not '.svn' in d[0]:
|
|
||||||
for filename in d[2]:
|
|
||||||
if filename.startswith('test_') and filename.endswith('.py'):
|
|
||||||
modname = ('tests' + "." + filename)[:-3].replace(os.sep,'.')
|
|
||||||
__import__(modname)
|
|
||||||
#sys.modules[modname].config = moduleconfig
|
|
||||||
alltests.append(sys.modules[modname].suite)
|
|
||||||
alltests_suite = unittest.TestSuite(alltests)
|
|
||||||
result = unittest.TextTestRunner(verbosity=2).run(alltests_suite)
|
|
||||||
print("""<tests xmlns='http://andyet.net/protocol/tests' ran='%s' errors='%s' fails='%s' success='%s' />""" % (result.testsRun, len(result.errors), len(result.failures), result.wasSuccessful()))
|
|
||||||
|
|
29
tests/test_overall.py
Normal file
29
tests/test_overall.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
import tabnanny
|
||||||
|
import compileall
|
||||||
|
|
||||||
|
class TestOverall(unittest.TestCase):
|
||||||
|
|
||||||
|
"""
|
||||||
|
Test overall package health by compiling and checking
|
||||||
|
code style.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def testModules(self):
|
||||||
|
"""Testing all modules by compiling them"""
|
||||||
|
src = '..%ssleekxmpp' % os.sep
|
||||||
|
if sys.version_info < (3, 0):
|
||||||
|
rx = re.compile('/[.]svn')
|
||||||
|
else:
|
||||||
|
rx = re.compile('/[.]svn|.*26.*')
|
||||||
|
self.failUnless(compileall.compile_dir(src, rx=rx, quiet=True))
|
||||||
|
|
||||||
|
def testTabNanny(self):
|
||||||
|
"""Testing that indentation is consistent"""
|
||||||
|
self.failIf(tabnanny.check('..%ssleekxmpp' % os.sep))
|
||||||
|
|
||||||
|
|
||||||
|
suite = unittest.TestLoader().loadTestsFromTestCase(TestOverall)
|
Loading…
Reference in a new issue