Skip to content

Commit

Permalink
More fixes for Python 3, a few testcases already pass
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Sep 23, 2010
1 parent 9bab8e2 commit 63030c0
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 20 deletions.
10 changes: 6 additions & 4 deletions logbook/base.py
Expand Up @@ -20,7 +20,8 @@
from weakref import ref as weakref
from datetime import datetime

from logbook.helpers import to_safe_json, parse_iso8601, cached_property, F
from logbook.helpers import to_safe_json, parse_iso8601, cached_property, \
F, _py3


# make sure to sync these up with _speedups.pyx
Expand All @@ -47,7 +48,7 @@

# on python 3 we can savely assume that frame filenames will be in
# unicode, on Python 2 we have to apply a trick.
if sys.version_info >= (3, 0):
if _py3:
def _convert_frame_filename(fn):
return fn
else:
Expand Down Expand Up @@ -581,8 +582,9 @@ def formatted_exception(self):
in case there was any.
"""
if self.exc_info is not None:
lines = traceback.format_exception(*self.exc_info)
rv = ''.join(lines).decode('utf-8', 'replace')
rv = ''.join(traceback.format_exception(*self.exc_info))
if not _py3:
rv = rv.decode('utf-8', 'replace')
return rv.rstrip()

@cached_property
Expand Down
29 changes: 20 additions & 9 deletions logbook/handlers.py
Expand Up @@ -25,7 +25,7 @@
from logbook.base import CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG, \
NOTSET, level_name_property, _missing, lookup_level, \
Flags, ContextObject, ContextStackManager
from logbook.helpers import rename, F
from logbook.helpers import rename, F, b


DEFAULT_FORMAT_STRING = (
Expand Down Expand Up @@ -62,6 +62,8 @@

SYSLOG_PORT = 514

_py3 = sys.version_info >= (3, 0)


def create_syshandler(application_name, level=NOTSET):
"""Creates the handler the operating system provides. On Unix systems
Expand Down Expand Up @@ -340,10 +342,10 @@ class HashingHandlerMixin(object):
def hash_record_raw(self, record):
"""Returns a hashlib object with the hash of the record."""
hash = hashlib.sha1()
hash.update('%d\x00' % record.level)
hash.update((record.channel or u'').encode('utf-8') + '\x00')
hash.update(record.filename.encode('utf-8') + '\x00')
hash.update(str(record.lineno))
hash.update(('%d\x00' % record.level).encode('ascii'))
hash.update((record.channel or u'').encode('utf-8') + b('\x00'))
hash.update(record.filename.encode('utf-8') + b('\x00'))
hash.update(b(str(record.lineno)))
return hash

def hash_record(self, record):
Expand Down Expand Up @@ -427,6 +429,11 @@ class StreamHandler(Handler, StringFormatterHandlerMixin):
with StreamHandler(my_stream):
pass
.. admonition:: Notes on the encoding
On Python 3, the encoding parameter is only used if a stream was
passed that was opened in binary mode.
"""

def __init__(self, stream, level=NOTSET, format_string=None,
Expand Down Expand Up @@ -458,10 +465,14 @@ def flush(self):

def format_and_encode(self, record):
"""Formats the record and encodes it to the stream encoding."""
enc = self.encoding
if enc is None:
enc = getattr(self.stream, 'encoding', None) or 'utf-8'
return (self.format(record) + u'\n').encode(enc, 'replace')
stream = self.stream
rv = self.format(record) + '\n'
if not _py3 or 'b' in stream.mode:
enc = self.encoding
if enc is None:
enc = getattr(stream, 'encoding', None) or 'utf-8'
rv = rv.encode(enc, 'replace')
return rv

def write(self, item):
"""Writes a bytestring to the stream."""
Expand Down
11 changes: 8 additions & 3 deletions logbook/helpers.py
Expand Up @@ -39,6 +39,11 @@ def F(format_string):
r'(?:T(\d{2}):(\d{2})(?::(\d{2}(?:\.\d+)?))?(Z|[+-]\d{2}:\d{2})?)?$'
)
_missing = object()
_py3 = sys.version_info >= (3, 0)
if _py3:
def b(x): return x.encode('ascii')
else:
def b(x): return x


can_rename_open_file = False
Expand Down Expand Up @@ -126,10 +131,10 @@ def to_safe_json(data):
"""Makes a data structure safe for JSON silently discarding invalid
objects from nested structures. This also converts dates.
"""
def _convert(obj, _py2=sys.version_info < (3, 0)):
def _convert(obj):
if obj is None:
return None
elif _py2 and isinstance(obj, str):
elif not _py3 and isinstance(obj, str):
return obj.decode('utf-8', 'replace')
elif isinstance(obj, (bool, int, long, float, unicode)):
return obj
Expand All @@ -142,7 +147,7 @@ def _convert(obj, _py2=sys.version_info < (3, 0)):
elif isinstance(obj, dict):
rv = {}
for key, value in obj.iteritems():
if _py2 and isinstance(key, str):
if not _py3 and isinstance(key, str):
key = key.decode('utf-8', 'replace')
else:
key = unicode(key)
Expand Down
12 changes: 8 additions & 4 deletions setup.py
Expand Up @@ -52,6 +52,7 @@ def inject_extra(record, handler):
# request.
"""

import os
import sys
from setuptools import setup, Extension, Feature
from distutils.command.build_ext import build_ext
Expand Down Expand Up @@ -93,14 +94,17 @@ def build_extension(self, ext):
raise BuildFailed()

cmdclass['build_ext'] = ve_build_ext
speedups = Feature('optional C speed-enhancement module', standard=True,
ext_modules=[Extension('logbook._speedups',
['logbook/_speedups.c'])])
if os.path.isfile('logbook/_speedups.c'):
speedups = Feature('optional C speed-enhancement module', standard=True,
ext_modules=[Extension('logbook._speedups',
['logbook/_speedups.c'])])
else:
speedups = None


def run_setup(with_binary):
features = {}
if with_binary:
if with_binary and speedups is not None:
features['speedups'] = speedups
setup(
name='Logbook',
Expand Down

0 comments on commit 63030c0

Please sign in to comment.