Skip to content

Commit

Permalink
Python 3 and PyPy support.
Browse files Browse the repository at this point in the history
- 100% test coverage.
  • Loading branch information
jamadden committed May 7, 2017
1 parent ebbdf12 commit 574cce6
Show file tree
Hide file tree
Showing 14 changed files with 377 additions and 87 deletions.
6 changes: 6 additions & 0 deletions .coveragerc
@@ -0,0 +1,6 @@
[run]
source = src

[report]
exclude_lines =
pragma: no cover
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -9,3 +9,5 @@ build/
dist/
*.egg-info/
.tox/
.coverage
htmlcov/
16 changes: 14 additions & 2 deletions .travis.yml
@@ -1,9 +1,21 @@
language: python
sudo: false
python:
- 2.7
- pypy-5.4.1
- 3.4
- 3.5
- 3.6
install:
- pip install .
- pip install -U pip setuptools
- pip install -U coverage coveralls
- pip install -U -e .[test]
script:
- python setup.py test -q
- coverage run -m zope.testrunner --test-path=src --auto-color --auto-progress
notifications:
email: false
after_success:
- coveralls
cache: pip
before_cache:
- rm -f $HOME/.cache/pip/log/debug.log
15 changes: 10 additions & 5 deletions CHANGES.txt → CHANGES.rst
@@ -1,14 +1,19 @@
=======
CHANGES
=======
=========
CHANGES
=========

4.0.0 (unreleased)
==================

- Add support for Python 3.4, 3.5, 3.6 and PyPy.

3.4.1 (2008-02-02)
------------------
==================

- Fix of 599 error on conflict error in request
see: http://mail.zope.org/pipermail/zope-dev/2008-January/030844.html

3.4.0 (2007-10-23)
------------------
==================

- Initial release independent of the main Zope tree.
7 changes: 7 additions & 0 deletions MANIFEST.in
@@ -1,3 +1,10 @@
include *.py
include *.txt
include *.rst
include buildout.cfg
include tox.ini
include .coveragerc
exclude .coverage
include .travis.yml
recursive-include src *.pt
recursive-include src *.zcml
File renamed without changes.
61 changes: 42 additions & 19 deletions setup.py
Expand Up @@ -18,26 +18,35 @@
##############################################################################
"""Setup for zope.app.debug package
$Id$
"""
import os
from setuptools import setup, find_packages

def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
with open(os.path.join(os.path.dirname(__file__), *rnames)) as f:
return f.read()

tests_require = [
'zope.component',
'zope.principalregistry',
'zope.site',
'zope.traversing',
'zope.testing',
'zope.testrunner',
]

setup(name='zope.app.debug',
version = '3.4.2dev',
version='4.0.0.dev0',
author='Zope Corporation and Contributors',
author_email='zope-dev@zope.org',
description='Zope Debug Mode',
long_description=(
read('README.txt')
read('README.rst')
+ '\n\n' +
read('CHANGES.txt')
read('CHANGES.rst')
),
keywords = "zope3 webdav",
classifiers = [
keywords="zope3 webdav",
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
Expand All @@ -46,18 +55,32 @@ def read(*rnames):
'Natural Language :: English',
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
'Framework :: Zope3'],
url='http://cheeseshop.python.org/pypi/zope.app.debug',
'Framework :: Zope3',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
],
url='http://github.com/zopefoundation/zope.app.debug',
license='ZPL 2.1',
packages=find_packages('src'),
package_dir = {'': 'src'},
package_dir={'': 'src'},
namespace_packages=['zope', 'zope.app'],
extras_require = dict(test=['zope.app.testing']),
install_requires=['setuptools',
'zope.publisher',
'zope.app.appsetup',
'zope.app.publication'
],
include_package_data = True,
zip_safe = False,
)
extras_require={
'test': tests_require,
},
tests_require=tests_require,
install_requires=[
'setuptools',
'zope.publisher',
'zope.app.appsetup',
'zope.app.publication'
],
include_package_data=True,
zip_safe=False,
)
8 changes: 1 addition & 7 deletions src/zope/__init__.py
@@ -1,7 +1 @@
# this is a namespace package
try:
import pkg_resources
pkg_resources.declare_namespace(__name__)
except ImportError:
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
__import__('pkg_resources').declare_namespace(__name__) # pragma: no cover
8 changes: 1 addition & 7 deletions src/zope/app/__init__.py
@@ -1,7 +1 @@
# this is a namespace package
try:
import pkg_resources
pkg_resources.declare_namespace(__name__)
except ImportError:
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
__import__('pkg_resources').declare_namespace(__name__) # pragma: no cover
122 changes: 75 additions & 47 deletions src/zope/app/debug/debug.py
Expand Up @@ -13,34 +13,50 @@
##############################################################################
"""Code to initialize the application server
$Id$
"""
from __future__ import print_function
__docformat__ = 'restructuredtext'

import base64, time
import urllib
from StringIO import StringIO
import base64
import time
try:
import urllib.parse as urllib
except ImportError:
import urllib
import sys

from pdb import Pdb
from io import BytesIO

from zope.publisher.publish import publish as _publish, debug_call
from zope.publisher.browser import TestRequest, setDefaultSkin
from zope.app.publication.browser import BrowserPublication
from zope.app.appsetup import config, database

try:
text_type = unicode
except NameError:
text_type = str

class Debugger(object):

def __init__(self, db=None, config_file=None):
pdb = Pdb

def __init__(self, db=None, config_file=None, stdout=None):
if db is None and config_file is None:
db = 'Data.fs'
config_file = 'site.zcml'

if config_file is not None:
config(config_file)
self.db = database(db)
self.stdout = stdout

@classmethod
def fromDatabase(cls, db):
inst = cls.__new__(cls)
inst.db = db
return inst
fromDatabase = classmethod(fromDatabase)

def root(self):
"""Get the top-level application object
Expand All @@ -60,13 +76,16 @@ def _request(self,

env = {}

if type(stdin) is str:
stdin = StringIO(stdin)
if isinstance(stdin, text_type):
stdin = stdin.encode("utf-8")

if isinstance(stdin, bytes):
stdin = BytesIO(stdin)

p=path.split('?')
if len(p)==1:
p = path.split('?')
if len(p) == 1:
env['PATH_INFO'] = p[0]
elif len(p)==2:
elif len(p) == 2:
env['PATH_INFO'], env['QUERY_STRING'] = p
else:
raise ValueError("Too many ?s in path", path)
Expand All @@ -77,7 +96,10 @@ def _request(self,
env.update(environment)

if basic:
env['HTTP_AUTHORIZATION']="Basic %s" % base64.encodestring(basic)
basic_bytes = basic.encode('ascii') if not isinstance(basic, bytes) else basic
basic64_bytes = base64.b64encode(basic_bytes)
basic64 = basic64_bytes.decode('ascii').strip()
env['HTTP_AUTHORIZATION'] = "Basic %s" % basic64


pub = publication(self.db)
Expand All @@ -89,8 +111,6 @@ def _request(self,
setDefaultSkin(request)
request.setPublication(pub)
if form:
# This requires that request class has an attribute 'form'
# (BrowserRequest has, TestRequest hasn't)
request.form.update(form)

return request
Expand All @@ -105,13 +125,14 @@ def publish(self, path='/', stdin='', *args, **kw):
request = _publish(request)
getStatus = getattr(request.response, 'getStatus', lambda: None)

headers = request.response.getHeaders()
headers.sort()
print 'Status %s\r\n%s\r\n\r\n%s' % (
request.response.getStatusString(),
'\r\n'.join([("%s: %s" % h) for h in headers]),
request.response.consumeBody(),
)
headers = sorted(request.response.getHeaders())

print(
'Status %s\r\n%s\r\n\r\n%s' % (
request.response.getStatusString(),
'\r\n'.join([("%s: %s" % h) for h in headers]),
request.response.consumeBody(),
), file=self.stdout or sys.stdout)
return time.time()-t, time.clock()-c, getStatus()

def run(self, *args, **kw):
Expand All @@ -125,42 +146,49 @@ def run(self, *args, **kw):
return time.time()-t, time.clock()-c, getStatus()

def debug(self, *args, **kw):
out = self.stdout or sys.stdout

class ZopePdb(self.Pdb):
done_pub = False
done_ob = False

def do_pub(self, arg):
if self.done_pub:
print('pub already done.', file=out)
return

self.do_s('')
self.do_s('')
self.do_c('')
self.done_pub = True

def do_ob(self, arg):
if self.done_ob:
print('ob already done.', file=out)
return

self.do_pub('')
self.do_c('')
self.done_ob = True

import pdb

class Pdb(pdb.Pdb):
def do_pub(self,arg):
if hasattr(self,'done_pub'):
print 'pub already done.'
else:
self.do_s('')
self.do_s('')
self.do_c('')
self.done_pub=1
def do_ob(self,arg):
if hasattr(self,'done_ob'):
print 'ob already done.'
else:
self.do_pub('')
self.do_c('')
self.done_ob=1

db=Pdb()
dbg = ZopePdb()

request = self._request(*args, **kw)
fbreak(db, _publish)
fbreak(db, debug_call)
fbreak(dbg, _publish)
fbreak(dbg, debug_call)

print '* Type c<cr> to jump to published object call.'
db.runcall(_publish, request)
print('* Type c<cr> to jump to published object call.',
file=out)
dbg.runcall(_publish, request)
return dbg


def fbreak(db, meth):
try:
meth = meth.im_func
meth = meth.__func__
except AttributeError:
pass
code = meth.func_code
code = meth.__code__
lineno = getlineno(code)
filename = code.co_filename
db.set_break(filename,lineno)
Expand Down
Empty file.

0 comments on commit 574cce6

Please sign in to comment.