Skip to content

Commit

Permalink
Update to version 1.0.0 Python 3 support
Browse files Browse the repository at this point in the history
Update to version 1.0.0 with support for python 3
  • Loading branch information
pjt0620 committed Sep 20, 2019
2 parents e810183 + 1c140a2 commit 3b92a35
Show file tree
Hide file tree
Showing 37 changed files with 478 additions and 382 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
language: python
dist: xenial
python:
- "2.7"
- "3.6.7"
before_install:
- sudo apt-get update -qq
- sudo apt-get -o Acquire::https::No-Cache=True -o Acquire::http::No-Cache=True update -qq
- sudo apt-get install python-bluetooth -qq -y
- pip install pyserial==3.1.1
- pip install coveralls
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
OpenXC Python Library Changelog
===============================

v1.0.0
----------
* Remove python 2.7 support
* Add python 3.6 support
* Known Issue: Tool openxc-dashboard does not display correctly in windows

v0.15.0
----------

Expand Down
11 changes: 9 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ OpenXC for Python

.. image:: /docs/_static/logo.png

:Version: 0.15.0
:Version: 1.0.0
:Web: http://openxcplatform.com
:Download: http://pypi.python.org/pypi/openxc/
:Documentation: http://python.openxcplatform.com
Expand All @@ -21,7 +21,7 @@ OpenXC for Python
:target: http://python.openxcplatform.com
:alt: Documentation Status

The OpenXC Python library (for Python 2.7) provides an interface to
The OpenXC Python library (for Python 3.6.7) provides an interface to
vehicle data from the OpenXC Platform. The primary platform for OpenXC
applications is Android, but for prototyping and testing, often it is
preferrable to use a low-overhead environment like Python when developing.
Expand All @@ -30,6 +30,13 @@ In addition to a port of the Android library API, the package also contains a
number of command-line tools for connecting to the CAN translator and
manipulating previously recorded vehicle data.

To package run "setup.py sdist bdist_wheel"
to push to pypi run "python -m twine upload dist/*"
Version files:
CHANGELOG.rst
README.rst
openxc/version.py
docs/index.rst
License
=======
Expand Down
16 changes: 8 additions & 8 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
master_doc = 'index'

# General information about the project.
project = u'OpenXC for Python'
copyright = u'2017, Ford Motor Company'
project = 'OpenXC for Python'
copyright = '2017, Ford Motor Company'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -196,8 +196,8 @@
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'OpenXCforPython.tex', u'OpenXC for Python Documentation',
u'Christopher Peplin', 'manual'),
('index', 'OpenXCforPython.tex', 'OpenXC for Python Documentation',
'Christopher Peplin', 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
Expand Down Expand Up @@ -226,8 +226,8 @@
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'openxcforpython', u'OpenXC for Python Documentation',
[u'Christopher Peplin'], 1)
('index', 'openxcforpython', 'OpenXC for Python Documentation',
['Christopher Peplin'], 1)
]

# If true, show URL addresses after external links.
Expand All @@ -240,8 +240,8 @@
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'OpenXCforPython', u'OpenXC for Python Documentation',
u'Christopher Peplin', 'OpenXCforPython', 'One line description of project.',
('index', 'OpenXCforPython', 'OpenXC for Python Documentation',
'Christopher Peplin', 'OpenXCforPython', 'One line description of project.',
'Miscellaneous'),
]

Expand Down
7 changes: 3 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ OpenXC for Python

.. image:: /_static/logo.png

:Version: 0.15.0
:Version: 1.0.0
:Web: http://openxcplatform.com
:Download: http://pypi.python.org/pypi/openxc/
:Documentation: http://python.openxcplatform.com
:Source: http://github.com/openxc/openxc-python/

The OpenXC Python library (for Python 2.7) provides an interface to
The OpenXC Python library (for Python 3.6) provides an interface to
vehicle data from the OpenXC Platform. The primary platform for OpenXC
applications is Android, but for prototyping and testing, often it is
preferrable to use a low-overhead environment like Python when developing.
Expand All @@ -19,8 +19,7 @@ In addition to a port of the Android library API, the package also contains a
number of command-line tools for connecting to the vehicle interface and
manipulating previously recorded vehicle data.

This Python package works with Python 2.7. Unfortunately we had to drop
support for Python 3 when we added the protobuf library as a dependency.
This Python package works with Python 3.6. For python 2.7 support use version 0.15.0.

For general documentation on the OpenXC platform, visit the main `OpenXC site`_.

Expand Down
8 changes: 4 additions & 4 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ Install Python and Pip
----------------------

This library (obviously) requires a Python language runtime - the OpenXC library
currently works with Python 2.7, but not Python 3.x.
supports python 3.x only, for python 2.x support use version 0.15.0.

- **Mac OS X and Linux**

Mac OS X and most Linux distributions already have a compatible Python
installed. Run ``python --version`` from a terminal to check - you need a
2.7.x version, such as 2.7.8.
3.6.x version, such as 3.6.8.

- **Windows**

#. Download and run the `Python 2.7.x MSI installer <https://www.python.org/downloads/release/python-2716/>`_.
#. Download and run the `Python 3.6.x MSI installer <https://www.python.org/downloads/>`_.
Make sure to select to option to ``Add python.exe to Path``.
#. Add the Python Scripts directory your PATH:
``PATH=%PATH%;c:\Python27\Scripts``. If you aren't sure how to edit your
``PATH=%PATH%;C:\Users\%username%\AppData\Local\Programs\Python\Python36-32\Scripts``. If you aren't sure how to edit your
``PATH``, see `this guide for all versions of Windows
<https://www.java.com/en/download/help/path.xml>`_. Log out and back in for
the change to take effect.
Expand Down
6 changes: 3 additions & 3 deletions fabfile.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from __future__ import with_statement


import os
from fabric.api import *
Expand Down Expand Up @@ -63,7 +63,7 @@ def version_to_tuple(version):

def make_tag():
if confirm(yellow("Tag this release?"), default=True):
print(green("The last 5 tags were: "))
print((green("The last 5 tags were: ")))
tags = local('git tag | tail -n 20', capture=True)
pp(sorted(tags.split('\n'), compare_versions, reverse=True))
prompt("New release tag in the format vX.Y[.Z]?", 'tag',
Expand All @@ -74,7 +74,7 @@ def make_tag():
local('git fetch --tags origin', capture=True)
else:
env.tag = latest_git_tag()
print(green("Using latest tag %(tag)s" % env))
print((green("Using latest tag %(tag)s" % env)))
return env.tag

@task
Expand Down
4 changes: 2 additions & 2 deletions openxc/controllers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import binascii

try:
from Queue import Queue
from Queue import Empty
from queue import Queue
from queue import Empty
except ImportError:
# Python 3
from queue import Queue
Expand Down
2 changes: 1 addition & 1 deletion openxc/controllers/serial.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Controller implementation for a virtual serial device."""
from __future__ import absolute_import

import time

from .base import Controller
Expand Down
2 changes: 1 addition & 1 deletion openxc/controllers/usb.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Controller implementation for an OpenXC USB device."""
from __future__ import absolute_import


import logging
import usb.core
Expand Down
9 changes: 5 additions & 4 deletions openxc/formats/binary.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Binary (Protobuf) formatting utilities."""
from __future__ import absolute_import


import binascii
import numbers
Expand Down Expand Up @@ -68,6 +68,7 @@ def deserialize(cls, data):
except UnicodeDecodeError as e:
LOG.warn("Unable to parse protobuf: %s", e)
else:
#return type(cls._protobuf_to_dict(message)['payload'])
return cls._protobuf_to_dict(message)

@classmethod
Expand Down Expand Up @@ -209,7 +210,7 @@ def _protobuf_to_dict(cls, message):
if can_message.HasField('id'):
parsed_message['id'] = can_message.id
if can_message.HasField('data'):
parsed_message['data'] = "0x%s" % binascii.hexlify(can_message.data)
parsed_message['data'] = "0x%s" % binascii.hexlify(can_message.data).decode("ascii")
if can_message.HasField('frame_format'):
if can_message.frame_format == openxc_pb2.RawMessage.STANDARD:
parsed_message['frame_format'] = "standard"
Expand All @@ -232,7 +233,7 @@ def _protobuf_to_dict(cls, message):
if diagnostic_message.HasField('negative_response_code'):
parsed_message['negative_response_code'] = diagnostic_message.negative_response_code
if diagnostic_message.HasField('payload'):
parsed_message['payload'] = "0x%s" % binascii.hexlify(diagnostic_message.payload)
parsed_message['payload'] = "0x%s" % binascii.hexlify(diagnostic_message.payload).decode("ascii")
elif message.type == message.SIMPLE:
simple_message = message.simple_message
parsed_message['name'] = simple_message.name
Expand Down Expand Up @@ -286,7 +287,7 @@ def _protobuf_to_dict(cls, message):
if request.HasField('pid'):
parsed_message['request']['pid'] = request.pid
if request.HasField('payload'):
parsed_message['request']['payload'] = "0x%s" % binascii.hexlify(request.payload)
parsed_message['request']['payload'] = "0x%s" % binascii.hexlify(request.payload).decode("ascii")
elif command.type == openxc_pb2.ControlCommand.PASSTHROUGH:
parsed_message['command'] = "passthrough"
parsed_message['bus'] = command.passthrough_mode_request.bus
Expand Down
4 changes: 2 additions & 2 deletions openxc/formats/json.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""JSON formatting utilities."""
from __future__ import absolute_import


import json

Expand Down Expand Up @@ -32,7 +32,7 @@ class JsonFormatter(object):

@classmethod
def deserialize(cls, message):
return json.loads(message.decode("utf8"))
return json.loads(message)

@classmethod
def serialize(cls, data):
Expand Down
20 changes: 10 additions & 10 deletions openxc/generator/message_sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
message set format.
"""

from __future__ import print_function

from collections import defaultdict
import operator
import logging
Expand All @@ -26,7 +26,7 @@ def __init__(self, name):
self.extra_sources = set()

def valid_buses(self):
valid_buses = [bus for bus in self.buses.values() if bus.valid()]
valid_buses = [bus for bus in list(self.buses.values()) if bus.valid()]
return sorted(valid_buses, key=operator.attrgetter('controller'))

def active_diagnostic_messages(self):
Expand All @@ -40,12 +40,12 @@ def all_diagnostic_messages(self):
yield message

def active_messages(self):
for bus in self.buses.values():
for bus in list(self.buses.values()):
for message in bus.active_messages():
yield message

def all_messages(self):
for bus in self.buses.values():
for bus in list(self.buses.values()):
for message in bus.sorted_messages():
yield message

Expand Down Expand Up @@ -94,7 +94,7 @@ def lookup_bus(self, name=None, controller=None):
if name is not None:
return self.buses.get(name, None)
else:
for bus in self.buses.values():
for bus in list(self.buses.values()):
if bus.controller == controller:
return bus

Expand Down Expand Up @@ -141,7 +141,7 @@ def parse(cls, filename, search_paths=None, skip_disabled_mappings=False):

# TODO could we parse the top level config file as if it were a mapping
# and avoid duplicating this code?
for message_id, message in data.get('messages', {}).items():
for message_id, message in list(data.get('messages', {}).items()):
message['id'] = message_id
mapping_config['messages'].append(message)

Expand All @@ -167,7 +167,7 @@ def _parse_diagnostic_messages(cls, message_set, messages):
@classmethod
def _parse_buses(cls, data):
buses = {}
for bus_name, bus_data in data.get('buses', {}).items():
for bus_name, bus_data in list(data.get('buses', {}).items()):
buses[bus_name] = CanBus(name=bus_name,
default_raw_can_mode=data.get('raw_can_mode', "off"),
default_max_message_frequency=data.get('max_message_frequency', 0),
Expand Down Expand Up @@ -254,15 +254,15 @@ def _parse_mappings(self, data, search_paths, skip_disabled_mappings):
LOG.warning("The bit number inversion setting is undefined "
"for the mapping '%s', but it " % mapping['mapping'] +
"is database-backed - assuming inverted")
for message in messages.values():
for message in list(messages.values()):
message.setdefault('bit_numbering_inverted',
True)

for message_id, message in messages.items():
for message_id, message in list(messages.items()):
message['id'] = message_id
message.setdefault('bus', bus_name)
message.setdefault('enabled', mapping_enabled)
all_messages.extend(messages.values())
all_messages.extend(list(messages.values()))

return {'messages': all_messages,
'commands': all_commands,
Expand Down
12 changes: 6 additions & 6 deletions openxc/generator/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self, message_set, enabled=True, **kwargs):
self.id = kwargs['id']

self.bus_name = kwargs['bus']
if not isinstance(self.bus_name, unicode):
if not isinstance(self.bus_name, str):
raise ConfigurationError("Bus name must be name of bus in "
"config, was '%s'" % self.bus_name)

Expand Down Expand Up @@ -145,9 +145,9 @@ def merge_message(self, data):
self.merge_signals(data['signals'])

def merge_signals(self, data):
for signal_name, signal_data in data.items():
for signal_name, signal_data in list(data.items()):
states = []
for name, raw_matches in signal_data.get('states', {}).items():
for name, raw_matches in list(signal_data.get('states', {}).items()):
for raw_match in raw_matches:
states.append(SignalState(raw_match, name))
signal_data.pop('states', None)
Expand Down Expand Up @@ -178,7 +178,7 @@ def sorted_signals(self):
yield signal

def enabled_signals(self):
for signal in self.signals.values():
for signal in list(self.signals.values()):
if signal.enabled:
yield signal

Expand All @@ -193,7 +193,7 @@ def active_signals(self):
def to_dict(self):
return {"name": self.name,
"signals": dict((key, value.to_dict())
for key, value in self.signals.items())}
for key, value in list(self.signals.items()))}

def __str__(self):
bus_index = self.message_set.lookup_bus_index(self.bus_name)
Expand Down Expand Up @@ -257,7 +257,7 @@ def enabled_signals(self):
yield signal

def sorted_messages(self):
for message in sorted(self.messages.values(),
for message in sorted(list(self.messages.values()),
key=operator.attrgetter('id')):
yield message

Expand Down

0 comments on commit 3b92a35

Please sign in to comment.