Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop python2 support and remove six dependency #491

Merged
merged 5 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion benchmarks/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
small number of fields.
"""

from __future__ import unicode_literals

import time

Expand Down
2 changes: 0 additions & 2 deletions docs/source/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ Contributing to Eliot

To run the full test suite, the Daemontools package should be installed.

All modules should have the ``from __future__ import unicode_literals`` statement, to ensure Unicode is used by default.

Coding standard is PEP8, with the only exception being camel case methods for the Twisted-related modules.
Some camel case methods remain for backwards compatibility reasons with the old coding standard.

Expand Down
1 change: 1 addition & 0 deletions eliot/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Eliot: Logging for Complex & Distributed Systems.
"""

from warnings import warn

# Expose the public API:
Expand Down
22 changes: 8 additions & 14 deletions eliot/_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
top-level actions.
"""

from __future__ import unicode_literals, absolute_import

import threading
from uuid import uuid4
from contextlib import contextmanager
Expand All @@ -16,7 +14,6 @@

from pyrsistent import field, PClass, optional, pmap_field, pvector
from boltons.funcutils import wraps
from six import text_type as unicode, PY3

from ._message import (
WrittenMessage,
Expand Down Expand Up @@ -114,9 +111,9 @@ def toString(self):
"""
Convert to a Unicode string, for serialization purposes.

@return: L{unicode} representation of the L{TaskLevel}.
@return: L{str} representation of the L{TaskLevel}.
"""
return "/" + "/".join(map(unicode, self._level))
return "/" + "/".join(map(str, self._level))

def next_sibling(self):
"""
Expand Down Expand Up @@ -569,7 +566,7 @@ class WrittenAction(PClass):
start_message = field(type=optional(WrittenMessage), mandatory=True, initial=None)
end_message = field(type=optional(WrittenMessage), mandatory=True, initial=None)
task_level = field(type=TaskLevel, mandatory=True)
task_uuid = field(type=unicode, mandatory=True, factory=unicode)
task_uuid = field(type=str, mandatory=True, factory=str)
# Pyrsistent doesn't support pmap_field with recursive types.
_children = pmap_field(TaskLevel, object)

Expand Down Expand Up @@ -838,7 +835,7 @@ def startTask(logger=None, action_type="", _serializers=None, **fields):
@return: A new L{Action}.
"""
action = Action(
logger, unicode(uuid4()), TaskLevel(level=[]), action_type, _serializers
logger, str(uuid4()), TaskLevel(level=[]), action_type, _serializers
)
action._start(fields)
return action
Expand Down Expand Up @@ -909,14 +906,11 @@ def log_call(
)

if action_type is None:
if PY3:
action_type = "{}.{}".format(
wrapped_function.__module__, wrapped_function.__qualname__
)
else:
action_type = wrapped_function.__name__
action_type = "{}.{}".format(
wrapped_function.__module__, wrapped_function.__qualname__
)

if PY3 and include_args is not None:
if include_args is not None:
from inspect import signature

sig = signature(wrapped_function)
Expand Down
2 changes: 0 additions & 2 deletions eliot/_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
Error-handling utility code.
"""

from __future__ import unicode_literals

from inspect import getmro


Expand Down
2 changes: 0 additions & 2 deletions eliot/_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
Support for maintaining an action context across generator suspension.
"""

from __future__ import unicode_literals, absolute_import

from sys import exc_info
from functools import wraps
from contextlib import contextmanager
Expand Down
7 changes: 2 additions & 5 deletions eliot/_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
Log messages and related utilities.
"""

from __future__ import unicode_literals

import time
from warnings import warn
from six import text_type as unicode

from pyrsistent import PClass, pmap_field

Expand Down Expand Up @@ -74,7 +71,7 @@ def __init__(self, contents, serializer=None):
You can also use L{Message.new} to create L{Message} objects.

@param contents: The contents of this L{Message}, a C{dict} whose keys
must be C{unicode}, or text that has been UTF-8 encoded to
must be C{str}, or text that has been UTF-8 encoded to
C{bytes}.

@param serializer: Either C{None}, or
Expand Down Expand Up @@ -141,7 +138,7 @@ class WrittenMessage(PClass):
@ivar _logged_dict: The originally logged dictionary.
"""

_logged_dict = pmap_field((str, unicode), object)
_logged_dict = pmap_field((str, str), object)

@property
def timestamp(self):
Expand Down
2 changes: 1 addition & 1 deletion eliot/_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def _safe_unicode_dictionary(dictionary):

@param dictionary: A L{dict} to serialize.

@return: A L{unicode} string representing the input dictionary as
@return: A L{str} string representing the input dictionary as
faithfully as can be done without putting in too much effort.
"""
try:
Expand Down
2 changes: 0 additions & 2 deletions eliot/_traceback.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
as well as common utilities for handling exception logging.
"""

from __future__ import unicode_literals

import traceback
import sys

Expand Down
44 changes: 15 additions & 29 deletions eliot/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,39 @@
Utilities that don't go anywhere else.
"""

from __future__ import unicode_literals

import sys
from types import ModuleType

from six import exec_, text_type as unicode, PY3


def safeunicode(o):
"""
Like C{unicode()}, but catches and swallows any raised exceptions.
Like C{str()}, but catches and swallows any raised exceptions.

@param o: An object of some sort.

@return: C{unicode(o)}, or an error message if that failed.
@rtype: C{unicode}
@return: C{str(o)}, or an error message if that failed.
@rtype: C{str}
"""
try:
return unicode(o)
return str(o)
except:
# Not much we can do about this...
return "eliot: unknown, unicode() raised exception"
return "eliot: unknown, str() raised exception"


def saferepr(o):
"""
Like C{unicode(repr())}, but catches and swallows any raised exceptions.
Like C{str(repr())}, but catches and swallows any raised exceptions.

@param o: An object of some sort.

@return: C{unicode(repr(o))}, or an error message if that failed.
@rtype: C{unicode}
@return: C{str(repr(o))}, or an error message if that failed.
@rtype: C{str}
"""
try:
return unicode(repr(o))
return str(repr(o))
except:
# Not much we can do about this...
return "eliot: unknown, unicode() raised exception"
return "eliot: unknown, str() raised exception"


def load_module(name, original_module):
Expand All @@ -52,19 +47,10 @@ def load_module(name, original_module):

@return: A new, distinct module.
"""
module = ModuleType(name)
if PY3:
import importlib.util
import importlib.util

spec = importlib.util.find_spec(original_module.__name__)
source = spec.loader.get_code(original_module.__name__)
else:
if getattr(sys, "frozen", False):
raise NotImplementedError("Can't load modules on Python 2 with PyInstaller")
path = original_module.__file__
if path.endswith(".pyc") or path.endswith(".pyo"):
path = path[:-1]
with open(path) as f:
source = f.read()
exec_(source, module.__dict__, module.__dict__)
module = ModuleType(name)
spec = importlib.util.find_spec(original_module.__name__)
source = spec.loader.get_code(original_module.__name__)
exec(source, module.__dict__, module.__dict__)
return module
32 changes: 13 additions & 19 deletions eliot/_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,8 @@
although in theory it could be done then as well.
"""

from __future__ import unicode_literals

from warnings import warn

import six

unicode = six.text_type

from pyrsistent import PClass, field as pyrsistent_field

from ._message import (
Expand Down Expand Up @@ -42,8 +36,8 @@ class ValidationError(Exception):


# Types that can be encoded to JSON:
_JSON_TYPES = {type(None), int, float, unicode, list, dict, bytes, bool}
_JSON_TYPES |= set(six.integer_types)
_JSON_TYPES = {type(None), int, float, str, list, dict, bytes, bool}
_JSON_TYPES |= set((int,))

RESERVED_FIELDS = (TASK_LEVEL_FIELD, TASK_UUID_FIELD, TIMESTAMP_FIELD)

Expand All @@ -60,7 +54,7 @@ class Field(object):
e.g. C{"path"}.

@ivar description: A description of what this field contains.
@type description: C{unicode}
@type description: C{str}
"""

def __init__(self, key, serializer, description="", extraValidator=None):
Expand Down Expand Up @@ -116,7 +110,7 @@ def forValue(klass, key, value, description):
@param value: The allowed value for the field.

@param description: A description of what this field contains.
@type description: C{unicode}
@type description: C{str}

@return: A L{Field}.
"""
Expand All @@ -139,12 +133,12 @@ def forTypes(klass, key, classes, description, extraValidator=None):
e.g. C{"path"}.

@ivar classes: A C{list} of allowed Python classes for this field's
values. Supported classes are C{unicode}, C{int}, C{float},
values. Supported classes are C{str}, C{int}, C{float},
C{bool}, C{long}, C{list} and C{dict} and C{None} (the latter
isn't strictly a class, but will be converted appropriately).

@param description: A description of what this field contains.
@type description: C{unicode}
@type description: C{str}

@param extraValidator: See description in L{Field.__init__}.

Expand Down Expand Up @@ -189,16 +183,16 @@ def fields(*fields, **keys):
]


REASON = Field.forTypes(REASON_FIELD, [unicode], "The reason for an event.")
TRACEBACK = Field.forTypes("traceback", [unicode], "The traceback for an exception.")
EXCEPTION = Field.forTypes("exception", [unicode], "The FQPN of an exception class.")
REASON = Field.forTypes(REASON_FIELD, [str], "The reason for an event.")
TRACEBACK = Field.forTypes("traceback", [str], "The traceback for an exception.")
EXCEPTION = Field.forTypes("exception", [str], "The FQPN of an exception class.")


class _MessageSerializer(object):
"""
A serializer and validator for messages.

@ivar fields: A C{dict} mapping a C{unicode} field name to the respective
@ivar fields: A C{dict} mapping a C{str} field name to the respective
L{Field}.
@ivar allow_additional_fields: If true, additional fields don't cause
validation failure.
Expand Down Expand Up @@ -300,7 +294,7 @@ def setstatus(key, status):
e.g. C{"yourapp:subsystem:yourtype"}.

@ivar description: A description of what this message means.
@type description: C{unicode}
@type description: C{str}
"""

def __init__(self, message_type, fields, description=""):
Expand All @@ -312,7 +306,7 @@ def __init__(self, message_type, fields, description=""):
type.

@param description: A description of what this message means.
@type description: C{unicode}
@type description: C{str}
"""
self.message_type = message_type
self.description = description
Expand Down Expand Up @@ -395,7 +389,7 @@ def dosomething(key):
C{"exception"} and C{"reason"} fields).

@ivar description: A description of what this action's messages mean.
@type description: C{unicode}
@type description: C{str}
"""

# Overrideable hook for testing; need staticmethod() so functions don't
Expand Down
6 changes: 1 addition & 5 deletions eliot/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
``WrittenAction`` and ``WrittenMessage`` objects.
"""

from __future__ import unicode_literals

from six import text_type as unicode

from pyrsistent import PClass, pmap_field, pset_field, discard

from ._message import WrittenMessage, TASK_UUID_FIELD
Expand Down Expand Up @@ -141,7 +137,7 @@ class Parser(PClass):
@ivar _tasks: Map from UUID to corresponding L{Task}.
"""

_tasks = pmap_field(unicode, Task)
_tasks = pmap_field(str, Task)

def add(self, message_dict):
"""
Expand Down
2 changes: 0 additions & 2 deletions eliot/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
Standardized serialization code.
"""

from __future__ import unicode_literals

from hashlib import md5

_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ"
Expand Down
2 changes: 0 additions & 2 deletions eliot/tai64n.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
@see: U{http://cr.yp.to/libtai/tai64.html}.
"""

from __future__ import unicode_literals

import struct
from binascii import b2a_hex, a2b_hex

Expand Down
Loading
Loading