Skip to content

Commit

Permalink
Merge pull request #1 from zopefoundation/py3
Browse files Browse the repository at this point in the history
Python 3 support
  • Loading branch information
mgedmin committed Oct 30, 2017
2 parents 430442b + 6f9fb17 commit 07e3d83
Show file tree
Hide file tree
Showing 20 changed files with 280 additions and 231 deletions.
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[run]
source = zope.app.server
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ build/
dist/
*.egg-info/
.tox/
.coverage
13 changes: 10 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
language: python
sudo: false
cache: pip
python:
- 2.7
- 3.4
- 3.5
- 3.6
install:
- python bootstrap.py
- bin/buildout
- pip install coveralls coverage
- pip install -e ".[test]"
script:
- bin/test -v1
- coverage run -m zope.testrunner --test-path=src -pvc
after_success:
- coveralls
notifications:
email: false
4 changes: 2 additions & 2 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
CHANGES
=======

3.6.1 (unreleased)
4.0.0 (unreleased)
------------------

- Nothing changed yet.
- Add support for Python 3.4, 3.5, and 3.6


3.6.0 (2011-03-23)
Expand Down
4 changes: 4 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ include buildout.cfg
recursive-include src *.in
recursive-include src *.xml
recursive-include src *.zcml

# added by check_manifest.py
include .coveragerc
include tox.ini
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
doctests = yes
111 changes: 63 additions & 48 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,53 +21,68 @@
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()


setup(name='zope.app.server',
version='3.6.1dev',
author='Zope Corporation and Contributors',
author_email='zope-dev@zope.org',
description='ZServer integration for Zope 3 Applications',
long_description=(
read('README.txt')
+ '\n\n' +
read('CHANGES.txt')
),
keywords = "zope3 zserver server http ftp wsgi",
classifiers = [
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
'Natural Language :: English',
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
'Framework :: Zope3'],
url='http://cheeseshop.python.org/pypi/zope.app.server',
license='ZPL 2.1',
packages=find_packages('src'),
package_dir = {'': 'src'},
namespace_packages=['zope', 'zope.app'],
extras_require = dict(test=['zope.app.testing']),
install_requires=['setuptools',
'zope.app.applicationcontrol',
'zope.app.appsetup >= 3.11',
'zope.app.publication',
'zope.app.wsgi',
'zope.configuration',
'zope.deprecation',
'zope.event',
'zope.interface',
'zope.publisher',
'zope.server',
'zope.password >= 3.6',
'zope.processlifetime',
'zdaemon',
'ZConfig',
'ZODB3',
],
include_package_data = True,
zip_safe = False,
)
setup(
name='zope.app.server',
version='4.0.0dev',
author='Zope Corporation and Contributors',
author_email='zope-dev@zope.org',
description='ZServer integration for Zope 3 Applications',
long_description=(
read('README.txt')
+ '\n\n' +
read('CHANGES.txt')
),
keywords="zope3 zserver server http ftp wsgi",
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Natural Language :: English',
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
'Framework :: Zope3',
],
url='https://github.com/zopefoundation/zope.app.server',
license='ZPL 2.1',
packages=find_packages('src'),
package_dir={'': 'src'},
namespace_packages=['zope', 'zope.app'],
extras_require=dict(
test=[
'zope.testrunner',
'zope.app.testing',
],
),
install_requires=[
'setuptools',
'zope.app.applicationcontrol',
'zope.app.appsetup >= 3.11',
'zope.app.publication',
'zope.app.wsgi',
'zope.configuration',
'zope.deprecation',
'zope.event',
'zope.interface',
'zope.publisher',
'zope.server >= 4.0',
'zope.password >= 3.6',
'zope.processlifetime',
'zdaemon',
'ZConfig',
'ZODB3',
],
include_package_data=True,
zip_safe=False,
)
10 changes: 6 additions & 4 deletions src/zope/app/server/ftp.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,26 @@
from zope.app.server.servertype import ServerType
import zope.interface


@zope.interface.implementer(IPublicationRequestFactory)
class FTPRequestFactory(object):
"""FTP Request factory
FTP request factories for a given database create FTP requests with
publications on the given database:
.. The test below has been disabled and moved to test_ftp.py (LP #257954)
.. The test below has been disabled and moved to test_ftp.py (LP #257954)
>>> from ZODB.tests.util import DB
>>> db = DB()
>>> factory = FTPRequestFactory(db)
>>> from cStringIO import StringIO
>>> request = factory(StringIO(''), {'credentials': None, 'path': '/'})
>>> from io import BytesIO
>>> request = factory(BytesIO(b''), {'credentials': None, 'path': '/'})
>>> request.publication.db is db
True
>>> db.close()
"""
zope.interface.implements(IPublicationRequestFactory)

def __init__(self, db):
self.publication = FTPPublication(db)
Expand All @@ -49,6 +50,7 @@ def __call__(self, input_stream, env):
request.setPublication(self.publication)
return request


server = ServerType(
PublisherFTPServer,
FTPRequestFactory,
Expand Down
61 changes: 34 additions & 27 deletions src/zope/app/server/mkzopeinstance.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
- server process control scripts and data
"""

from __future__ import print_function

import optparse
import os
import shutil
Expand All @@ -30,13 +33,14 @@
from zope.password import password
from zope.app.applicationcontrol import zopeversion


def main(argv=None, from_checkout=False):
"""Top-level script function to create a new Zope instance."""
if argv is None:
argv = sys.argv
try:
options = parse_args(argv, from_checkout)
except SystemExit, e:
except SystemExit as e:
if e.code:
return 2
else:
Expand All @@ -46,7 +50,7 @@ def main(argv=None, from_checkout=False):
return app.process()
except KeyboardInterrupt:
return 1
except SystemExit, e:
except SystemExit as e:
return e.code


Expand All @@ -59,33 +63,33 @@ def __init__(self, options):
def read_input_line(self, prompt):
# The tests replace this to make sure the right things happen.
if not self.options.interactive:
print >>sys.stderr, ('Error: Tried to ask for user input in'
' non-interactive mode.')
print('Error: Tried to ask for user input in'
' non-interactive mode.', file=sys.stderr)
sys.exit(1)
return raw_input(prompt)

def read_password(self, prompt):
# The tests replace this to make sure the right things happen.
if not self.options.interactive:
print >>sys.stderr, ('Error: Tried to ask for user input in'
' non-interactive mode.')
print('Error: Tried to ask for user input in'
' non-interactive mode.', file=sys.stderr)
sys.exit(1)
import getpass
try:
return getpass.getpass(prompt)
except KeyboardInterrupt:
# The cursor was left on the same line as the prompt,
# which we don't like. Print a blank line.
print
print()
raise

def process(self):
options = self.options

# make sure we can find the skeleton
if not os.path.isdir(options.skeleton):
print >>sys.stderr, "skeleton directory", options.skeleton
print >>sys.stderr, "does not exist or is not a directory"
print("skeleton directory", options.skeleton, file=sys.stderr)
print("does not exist or is not a directory", file=sys.stderr)
return 1

# create the destination
Expand All @@ -95,13 +99,13 @@ def process(self):
if not os.path.exists(options.destination):
try:
os.mkdir(options.destination)
except OSError, e:
print >>sys.stderr, "could not create instance home:", e
except OSError as e:
print("could not create instance home:", e, file=sys.stderr)
return 1
elif not os.path.isdir(options.destination):
print >>sys.stderr, options.destination, "is not a directory"
print >>sys.stderr, ("(instance homes cannot be created in"
" non-directories)")
print(options.destination, "is not a directory", file=sys.stderr)
print("(instance homes cannot be created in non-directories)",
file=sys.stderr)
return 1

if not options.username:
Expand All @@ -114,6 +118,8 @@ def process(self):
options.password = self.get_password()

options.password = password_manager.encodePassword(options.password)
if not isinstance(options.password, str):
options.password = options.password.decode()

# now create the instance!
self.copy_skeleton()
Expand All @@ -132,7 +138,7 @@ def get_skeltarget(self):
while 1:
skeltarget = self.read_input_line("Directory: ").strip()
if skeltarget == '':
print >>sys.stderr, 'You must specify a directory'
print('You must specify a directory', file=sys.stderr)
continue
return os.path.expanduser(skeltarget)

Expand All @@ -142,7 +148,7 @@ def get_username(self):
while 1:
username = self.read_input_line("Username: ").strip()
if not username:
print >>sys.stderr, "You must specify an administrative user"
print("You must specify an administrative user", file=sys.stderr)
continue
return username

Expand All @@ -151,15 +157,15 @@ def get_password(self):
while 1:
password = self.read_password("Password: ")
if not password:
print >>sys.stderr, "Password may not be empty"
print("Password may not be empty", file=sys.stderr)
continue
if password != password.strip() or password.split() != [password]:
print >>sys.stderr, "Password may not contain spaces"
print("Password may not contain spaces", file=sys.stderr)
continue
break
again = self.read_password("Verify password: ")
if again != password:
print >>sys.stderr, "Password not verified!"
print("Password not verified!", file=sys.stderr)
sys.exit(1)
return password

Expand All @@ -171,13 +177,13 @@ def get_password_manager(self):
for name, manager in password.managers:
if name == self.options.password_manager:
return (name, manager)
print >>sys.stderr, "Unknown password manager!"
print("Unknown password manager!", file=sys.stderr)
sys.exit(1)

self.print_message(PASSWORD_MANAGER_MESSAGE)
for i, (name, manager) in enumerate(password.managers):
print "% i. %s" % (i + 1, name)
print
print("% i. %s" % (i + 1, name))
print()
self.need_blank_line = True
while 1:
password_manager = self.read_input_line(
Expand All @@ -190,22 +196,23 @@ def get_password_manager(self):
if index > 0 and index <= len(password.managers):
index -= 1
break
print >>sys.stderr, "You must select a password manager"
print "%r password manager selected" % password.managers[index][0]
print("You must select a password manager", file=sys.stderr)
print("%r password manager selected" % password.managers[index][0])
return password.managers[index]

def print_message(self, message):
if self.need_blank_line:
print
print()
self.need_blank_line = False
print message
print(message)

def copy_skeleton(self):
options = self.options
# TODO we should be able to compute the script
script = os.path.abspath(sys.argv[0])
zope_home = os.path.dirname(os.path.dirname(script))
zope_init = os.path.dirname(os.path.abspath(zope.app.__file__))
zope_init = os.path.dirname(os.path.dirname(
os.path.abspath(zope.app.server.__file__)))
software_home = os.path.dirname(os.path.dirname(zope_init))
self.replacements = [
("<<USERNAME>>", options.username),
Expand Down
Loading

0 comments on commit 07e3d83

Please sign in to comment.