<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>firepython/_setup_common.py</filename>
    </added>
    <added>
      <filename>pavement.py</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,8 +1,8 @@
 TODO
 ====
- - convert from ``setuptools`` to ``Paver``, port all ``rakefile``` tasks to ``pavement`` tasks
+ - port all ``rakefile``` tasks to ``pavement`` tasks
  - get the dependency stuff sorted out with regard to ``jsonpickle``
-   so that the embedding step is unnecessary
+   and ``gprof2dot`` so that the embedding/patching step is unnecessary
  - add an entry point for using the middleware with ``Paste``
  - break dependency on filesystem layout with regard to ``firelogger``,
    possible when converting from ``rake`` to ``Paver``</diff>
      <filename>TODO.txt</filename>
    </modified>
    <modified>
      <diff>@@ -4,10 +4,11 @@
 #
 # for usage see readme.md or http://github.com/darwin/firepython
 #
-from firepython._const import *
-
 __all__ = [
+    '__api_version__',
     '__version__',
 ]
 
-__version__ = '0.5'
+__api_version__ = '0.5'
+# ^--- corresponds to api version of firelogger
+__version__ = '0.6.0'   # for python package releases</diff>
      <filename>firepython/__init__.py</filename>
    </modified>
    <modified>
      <diff>@@ -14,9 +14,14 @@ except ImportError:
 
 import jsonpickle
 
+try:
+    import gprof2dot
+except ImportError:
+    gprof2dot = None
+
 import firepython
 import firepython.utils
-import firepython.gprof2dot as gprof2dot
+import firepython._const as CONST
 from firepython.handlers import ThreadBufferedHandler
 
 __all__ = [
@@ -51,14 +56,19 @@ class FirePythonBase(object):
         self._handler = None
 
     def _version_check(self, version_header):
-        version = version_header.strip()
-        if version == '':
+        firelogger_api_version = version_header.strip()
+        if firelogger_api_version == '':
             logging.info('FireLogger not detected')
             return False
-        if firepython.__version__ != version:
-            self._client_message += ('Warning: FireLogger (client) has version %s, but FirePython (server) is %s. ' % (version, firepython.__version__))
-            logging.warning('FireLogger (client) has version %s, but FirePython (server) is %s',
-                            version, firepython.__version__)
+        if firepython.__api_version__ != firelogger_api_version:
+            self._client_message += (
+                'Warning: FireLogger (client) has version %s, but '
+                'FirePython (server) is %s. ' % (firelogger_api_version,
+                                                 firepython.__api_version__)
+            )
+            logging.warning('FireLogger has version %s, but FirePython '
+                            '(server) is version %s', firelogger_api_version,
+                            firepython.__api_version__)
         return True
 
     def _password_check(self, token):
@@ -88,14 +98,17 @@ class FirePythonBase(object):
 
     def _check(self, env):
         self._client_message = ''
-        self._profile_enabled = env.get(firepython.FIRELOGGER_PROFILER_ENABLED_HEADER, '') != ''
-        self._appstats_enabled = env.get(firepython.FIRELOGGER_APPSTATS_ENABLED_HEADER, '') != ''
-        if (self._check_agent and
-            not self._version_check(env.get(firepython.FIRELOGGER_VERSION_HEADER, ''))):
+        self._appstats_enabled = \
+            env.get(firepython.FIRELOGGER_APPSTATS_ENABLED_HEADER, '') != ''
+        self._profile_enabled = \
+            env.get(CONST.FIRELOGGER_PROFILER_ENABLED, '') != ''
+        if (self._check_agent and not
+              self._version_check(
+                env.get(CONST.FIRELOGGER_VERSION_HEADER, ''))):
             return False
         if ((self._password and not
               self._password_check(
-                env.get(firepython.FIRELOGGER_AUTH_HEADER, '')))):
+                env.get(CONST.FIRELOGGER_AUTH_HEADER, '')))):
             return False
         # If _password is set, skip _appengine_check()
         if (not self._password and not self._appengine_check()):
@@ -113,7 +126,7 @@ class FirePythonBase(object):
         return (exc_type, exc_value, exc_traceback)
 
     def _handle_internal_exception(self, e):
-        if firepython.RAZOR_MODE: # in razor mode hurt web server
+        if CONST.RAZOR_MODE: # in razor mode hurt web server
             raise e
         # in non-razor mode report internal error to firepython addon
         exc_info = self._sanitize_exc_info(sys.exc_info())
@@ -130,7 +143,7 @@ class FirePythonBase(object):
             data['extension_data'] = extension_data
         try:
             data = jsonpickle.encode(data, unpicklable=False,
-                                     max_depth=firepython.JSONPICKLE_DEPTH)
+                                     max_depth=CONST.JSONPICKLE_DEPTH)
         except Exception, e:
             # this exception may be fired, because of buggy __repr__ or
             # __str__ implementations on various objects
@@ -138,7 +151,7 @@ class FirePythonBase(object):
             try:
                 data = jsonpickle.encode({&quot;errors&quot;: errors },
                                          unpicklable=False,
-                                         max_depth=firepython.JSONPICKLE_DEPTH)
+                                         max_depth=CONST.JSONPICKLE_DEPTH)
             except Exception, e:
                 # even unable to serialize error message
                 data = jsonpickle.encode(
@@ -147,7 +160,7 @@ class FirePythonBase(object):
                         }
                     },
                     unpicklable=False,
-                    max_depth=firepython.JSONPICKLE_DEPTH
+                    max_depth=CONST.JSONPICKLE_DEPTH
                 )
         data = data.encode('utf-8')
         data = data.encode('base64')
@@ -156,7 +169,7 @@ class FirePythonBase(object):
     def republish(self, headers):
         firelogger_headers = []
         for key, value in headers.iteritems():
-            if firepython.FIRELOGGER_RESPONSE_HEADER.match(key):
+            if CONST.FIRELOGGER_RESPONSE_HEADER.match(key):
                 firelogger_headers.append((key, value))
 
         self._handler.republish(firelogger_headers)
@@ -222,7 +235,7 @@ class FirePythonBase(object):
                     try:
                         d = {}
                         for k,v in t.tb_frame.f_locals.iteritems():
-                            if firepython.DEEP_LOCALS:
+                            if CONST.DEEP_LOCALS:
                                 d[unicode(k)] = v
                             else:
                                 d[unicode(k)] = repr(v)
@@ -273,12 +286,18 @@ class FirePythonBase(object):
         if not self._profile_enabled or not hasattr(self, '_prof'):
             return None
 
+        if not gprof2dot:
+            logging.warn('failed to import ``gprof2dot``, will not profile')
+            return None
+
         self._prof.create_stats()
         parser = gprof2dot.PstatsParser(self._prof)
+
         def get_function_name((filename, line, name)):
             module = os.path.splitext(filename)[0]
             module_pieces = module.split(os.path.sep)
             return &quot;%s:%d:%s&quot; % (&quot;/&quot;.join(module_pieces[-4:]), line, name)
+
         parser.get_function_name = get_function_name
         output = StringIO()
         gprof = parser.parse()
@@ -393,7 +412,7 @@ class FirePythonWSGI(FirePythonBase):
         # firepython is enabled or we have a client message we want to communicate in headers
         client_message = self._client_message
 
-        # asking why? http://jjinux.blogspot.com/2006/10/python-modifying-counter-in-closure.html
+        # asking why? see __ref_pymod_counter__
         closure = [&quot;200 OK&quot;, [], None]
         extension_data = {}  # Collect extension data here
         sio = StringIO()
@@ -416,18 +435,22 @@ class FirePythonWSGI(FirePythonBase):
             
         # run app
         try:
-            if check: 
-                app = self._profile_wrap(self._app)
-            app_iter = app(environ, faked_start_response)
-            output = list(app_iter)
-        except Exception:
-            logging.exception(sys.exc_info()[1])
-            raise
-        except:
-            logging.warning(&quot;DeprecationWarning: raising a &quot;
-                            &quot;string exception is deprecated&quot;)
-            logging.exception(sys.exc_info()[0])
-            raise
+            # the nested try-except block within
+            # a try-finally block is so that we stay
+            # python2.3 compatible
+            try:
+                if check:
+                    app = self._profile_wrap(self._app)
+                app_iter = app(environ, faked_start_response)
+                output = list(app_iter)
+            except Exception:
+                logging.exception(sys.exc_info()[1])
+                raise
+            except:
+                logging.warning(&quot;DeprecationWarning: raising a &quot;
+                                &quot;string exception is deprecated&quot;)
+                logging.exception(sys.exc_info()[0])
+                raise
         finally:
             # Output the profile first, so we can see any errors in profiling.
             if check: 
@@ -444,5 +467,5 @@ class FirePythonWSGI(FirePythonBase):
 
 
 
-# ref:pymod-counter:
-#   http://jjinux.blogspot.com/2006/10/python-modifying-counter-in-closure.html
+__ref_pymod_counter__ = \
+&quot;http://jjinux.blogspot.com/2006/10/python-modifying-counter-in-closure.html&quot;</diff>
      <filename>firepython/middleware.py</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 # -*- mode: python; coding: utf-8 -*-
 import sys
-from firepython import __version__
+from firepython import __api_version__
 import firepython._const as CONST
 
 
@@ -35,7 +35,7 @@ def json_encode(data):
     return json.dumps(data, cls=TolerantJSONEncoder)
 
 
-def get_version_header(version=__version__):
+def get_version_header(version=__api_version__):
     return (CONST.FIRELOGGER_VERSION_HEADER, version)
 
 </diff>
      <filename>firepython/utils.py</filename>
    </modified>
    <modified>
      <diff>@@ -4,6 +4,8 @@ import os
 import sys
 import nose
 
+HERE = os.path.dirname(os.path.abspath(__file__))
+TESTS = os.path.join(HERE, 'tests')
 FPY_MODS = [
     'firepython.utils',
     'firepython.middleware',
@@ -27,6 +29,8 @@ if W_ITESTS:
 
 
 def main():
+    if not TESTS in NOSE_ARGV:
+        NOSE_ARGV.append(TESTS)
     return nose.main(argv=NOSE_ARGV)
 
 </diff>
      <filename>run_tests.py</filename>
    </modified>
    <modified>
      <diff>@@ -1,41 +1,33 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+import os
 import sys
-from setuptools import setup, find_packages
-
-import firepython
-
-
-SETUP_ARGS = dict(
-    name='FirePython',
-    version=firepython.__version__,
-    description='Python logging console integrated into Firebug',
-    long_description=firepython.__doc__,
-    author='Antonin Hildebrand',
-    author_email='antonin@hildebrand.cz',
-    url='http://firepython.binaryage.com',
-    packages=find_packages(exclude=['tests']),
-    classifiers=[
-        'Development Status :: 4 - Beta',
-        'Environment :: Web Environment',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: BSD License',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python',
-        'Topic :: Software Development :: Bug Tracking',
-        'Topic :: Software Development :: Quality Assurance',
-        'Topic :: Software Development :: Testing',
-        'Topic :: System :: Logging',
-    ],
-    test_suite='nose.collector',
-    include_package_data=True,
-    zip_safe=False,
-)
 
-def main():
+
+def python23_compat_main():
+    try:
+        from setuptools import setup
+    except ImportError:
+        from distutils.core import setup
+
+    from firepython._setup_common import SETUP_ARGS
     setup(**SETUP_ARGS)
+
     return 0
 
 
+def paver_main():
+    if os.path.exists(&quot;paver-minilib.zip&quot;):
+        sys.path.insert(0, &quot;paver-minilib.zip&quot;)
+
+    import paver.tasks
+    return paver.tasks.main()
+
+
+def main():
+    if sys.version_info[:2] &lt;= (2, 3):
+        return python23_compat_main()
+    else:
+        return paver_main()
+
+
 if __name__ == '__main__':
     sys.exit(main())</diff>
      <filename>setup.py</filename>
    </modified>
    <modified>
      <diff>@@ -39,7 +39,7 @@ def get_app():
 def get_filterable_env():
     env = {}
     env[FC.FIRELOGGER_PROFILER_ENABLED] = 'yes'
-    env[FC.FIRELOGGER_VERSION_HEADER] = FPY.__version__
+    env[FC.FIRELOGGER_VERSION_HEADER] = FPY.__api_version__
     env[FC.FIRELOGGER_AUTH_HEADER] = FU.get_auth_token('snarf')
     return env
 </diff>
      <filename>tests/itest_middleware.py</filename>
    </modified>
    <modified>
      <diff>@@ -6,8 +6,8 @@ IMPORT_MODS = [
     'firepython.utils',
     'firepython.middleware',
     'firepython.handlers',
-    'firepython.gprof2dot',
     'firepython._const',
+    'firepython._setup_common',
 ]
 
 </diff>
      <filename>tests/test_basic.py</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,7 @@
 import nose.tools as NT
 import mock
 
-import firepython as FPY
+import firepython._const as CONST
 import firepython.utils as FU
 
 
@@ -34,5 +34,5 @@ def test_get_auth_token():
     yield NT.assert_equal, EXPECTED_AUTH_TOK, ret
 
 
-EXPECTED_VERSION_HEADER = (FPY.FIRELOGGER_VERSION_HEADER, 'bork')
+EXPECTED_VERSION_HEADER = (CONST.FIRELOGGER_VERSION_HEADER, 'bork')
 EXPECTED_AUTH_TOK = 'c5d00db3f939c1cc523f57d67e5cc319'</diff>
      <filename>tests/test_utils.py</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>firepython/gprof2dot.py</filename>
    </removed>
    <removed>
      <filename>jsonpickle/COPYING</filename>
    </removed>
    <removed>
      <filename>jsonpickle/__init__.py</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>2c54de672572798037b0747a470711d208dcf919</id>
    </parent>
  </parents>
  <author>
    <name>Dan Buch</name>
    <email>daniel.buch@gmail.com</email>
  </author>
  <url>http://github.com/darwin/firepython/commit/5027efb73e42d24fbcff8e81d6bde8de0b6158ae</url>
  <id>5027efb73e42d24fbcff8e81d6bde8de0b6158ae</id>
  <committed-date>2009-10-24T11:46:26-07:00</committed-date>
  <authored-date>2009-07-26T17:47:22-07:00</authored-date>
  <message>did majority of conversion from rake to Paver
 - making sure all is python2.3 compatible, including the
   setup.py file, which is not generated but instead
   chooses based on sys.version_info whether to use
   Paver or (distutils/setuptools)
 - verified that a 2.3 egg is buildable
 - verified that test suite may be run by 2.3
 - broke out concepts of __version__ and __api_version__
   so that FirePython may have its own release series
   independent of firelogger
 - removed private copies of gprof2dot and jsonpickle
   in prep for test install runs with GAE</message>
  <tree>fac5ae01af2fefe06dd23f8c3ce0c9e1f9daf3c6</tree>
  <committer>
    <name>Dan Buch</name>
    <email>daniel.buch@gmail.com</email>
  </committer>
</commit>
