diff --git a/CHANGES b/CHANGES
index 23dc89f..f6884e2 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,8 +1,9 @@
 Changes
 =======
 
-Next
-----
+0.16.1
+------
+- Python 2/3 bugfixes (#239)
 - Add support for Maps v4 (#228).
 
 0.16.0 (2018-05-08)
diff --git a/mapbox/__init__.py b/mapbox/__init__.py
index d07d0ef..aa93a1d 100644
--- a/mapbox/__init__.py
+++ b/mapbox/__init__.py
@@ -1,5 +1,5 @@
 # mapbox
-__version__ = "0.16.0"
+__version__ = "0.16.1"
 
 from .services.datasets import Datasets
 from .services.directions import Directions
diff --git a/mapbox/compat.py b/mapbox/compat.py
new file mode 100644
index 0000000..c01ed1b
--- /dev/null
+++ b/mapbox/compat.py
@@ -0,0 +1,6 @@
+import sys
+
+if sys.version_info[0] >= 3:  # pragma: no cover
+    string_type = str
+else:  # pragma: no cover
+    string_type = basestring
diff --git a/mapbox/encoding.py b/mapbox/encoding.py
index a6e6f96..40530d0 100644
--- a/mapbox/encoding.py
+++ b/mapbox/encoding.py
@@ -61,7 +61,9 @@ def encode_waypoints(features, min_limit=None, max_limit=None, precision=6):
     return a string encoded in waypoint-style used by certain mapbox APIs
     ("lon,lat" pairs separated by ";")
     """
-    coords = ['{lon},{lat}'.format(lon=round(lon, precision), lat=round(lat, precision))
+    coords = ['{lon},{lat}'.format(
+                  lon=float(round(lon, precision)),
+                  lat=float(round(lat, precision)))
               for lon, lat in read_points(features)]
 
     if min_limit is not None and len(coords) < min_limit:
@@ -88,7 +90,7 @@ def encode_coordinates_json(features):
     """Given an iterable of features
     return a JSON string to be used as the request body for the distance API:
     a JSON object, with a key coordinates,
-    which has an array of [ Longitude, Latitidue ] pairs
+    which has an array of [ Longitude, Lattitude ] pairs
     """
     coords = {
         'coordinates': list(read_points(features))}
diff --git a/mapbox/services/directions.py b/mapbox/services/directions.py
index 8df3400..30dd34b 100644
--- a/mapbox/services/directions.py
+++ b/mapbox/services/directions.py
@@ -6,6 +6,7 @@ from uritemplate import URITemplate
 
 from mapbox.encoding import encode_waypoints as encode_coordinates
 from mapbox.services.base import Service
+from mapbox.compat import string_type
 from mapbox import errors
 
 
@@ -118,7 +119,7 @@ class Directions(Service):
         if radius is None:
             return None
 
-        if isinstance(radius, str):
+        if isinstance(radius, string_type):
             if radius != 'unlimited':
                 raise errors.InvalidParameterError(
                     '{0} is not a valid radius'.format(radius))

direction validate_snapping behavior differs by Python version
Another fun Python 2/3 issue

The `_validate_snapping` method returns (bearings, radii) tuples.

In Python 3, we get the correct behavior

```python
>>> from mapbox.services import directions
>>> d = directions.Directions()
>>> d._validate_snapping([(1, 1, 1), u'unlimited'], [None, None])
([(1, 1), None], [1, 'unlimited'])
```

In Python 2, we get an Expection

```python
>>> from mapbox.services import directions
>>> d = directions.Directions()
>>> d._validate_snapping([(1, 1, 1), u'unlimited'], [None, None])
------------------------------------------------------------------------
InvalidParameterError                  Traceback (most recent call last)
<ipython-input-3-1dc0bc40d399> in <module>()
----> 1 d._validate_snapping([(1, 1, 1), u'unlimited'], [None, None])

/Users/mperry/env/sdk27/lib/python2.7/site-packages/mapbox/services/directions.pyc in _validate_snapping(self, snaps, features)
     93                     except ValueError:
     94                         raise errors.InvalidParameterError(
---> 95                             'waypoint snapping should contain 3 elements: '
     96                             '(bearing, angle, range)')
     97                     self._validate_radius(radius)

InvalidParameterError: waypoint snapping should contain 3 elements: (bearing, angle, range)
```
diff --git a/tests/test_directions.py b/tests/test_directions.py
index d9c4fe4..4c5759b 100644
--- a/tests/test_directions.py
+++ b/tests/test_directions.py
@@ -239,10 +239,17 @@ def test_validate_radius_none():
     assert service._validate_radius(None) is None
 
 
+def test_validate_radius_unlimited():
+    service = mapbox.Directions(access_token='pk.test')
+    assert service._validate_radius('unlimited') == 'unlimited'
+
+
 def test_validate_radius_invalid():
     service = mapbox.Directions(access_token='pk.test')
     with pytest.raises(mapbox.errors.InvalidParameterError) as e:
         service._validate_radius(-1)
+    with pytest.raises(mapbox.errors.InvalidParameterError) as e:
+        service._validate_radius('nothing')
 
 
 def test_invalid_bearing_domain():
@@ -256,3 +263,11 @@ def test_bearings_without_radius():
     with pytest.raises(TypeError):
         mapbox.Directions(access_token='pk.test').directions(
             waypoint_snapping=[(270, 45), (270, 45)])
+
+
+def test_validate_snapping():
+    service = mapbox.Directions(access_token='pk.test')
+    snaps = service._validate_snapping(
+        [(1, 1, 1), u'unlimited'], [None, None])
+
+    assert snaps == ([(1, 1), None], [1, 'unlimited'])
diff --git a/tests/test_encoding.py b/tests/test_encoding.py
index 72b5152..8fb4b5e 100644
--- a/tests/test_encoding.py
+++ b/tests/test_encoding.py
@@ -128,3 +128,16 @@ def test_encode_coordinates_json():
     assert expected == json.loads(encode_coordinates_json(gj_point_features))
     assert expected == json.loads(encode_coordinates_json(gj_multipoint_features))
     assert expected == json.loads(encode_coordinates_json(gj_line_features))
+
+
+def test_encode_waypoints_rounding():
+    expected = "1.0,0.0"
+    int_coord_features = [{
+        "type": "Feature",
+        "geometry": {
+            "type": "Point",
+            "coordinates": [1, 0]
+        },
+        "properties": {}}]
+
+    assert expected == encode_waypoints(int_coord_features)

pip install -e .[test]
parse_log_pytest
pytest
pytest
3.6
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs @ file:///opt/conda/conda-bld/attrs_1642510447205/work
boto3==1.23.10
botocore==1.26.10
CacheControl==0.12.14
certifi==2021.5.30
charset-normalizer==2.0.12
coverage==6.2
coveralls==3.3.1
distlib==0.3.9
docopt==0.6.2
filelock==3.4.1
idna==3.10
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
iso3166==2.1.1
jmespath==0.10.0
-e git+https://github.com/mapbox/mapbox-sdk-py.git@483297046c4db2ea5defe791f755dc5c6c193ed6#egg=mapbox
more-itertools @ file:///tmp/build/80754af9/more-itertools_1637733554872/work
msgpack==1.0.5
packaging @ file:///tmp/build/80754af9/packaging_1637314298585/work
platformdirs==2.4.0
pluggy @ file:///tmp/build/80754af9/pluggy_1615976315926/work
polyline==1.4.0
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pyparsing @ file:///tmp/build/80754af9/pyparsing_1635766073266/work
pytest==6.2.4
pytest-cov==4.0.0
python-dateutil==2.9.0.post0
requests==2.27.1
responses==0.17.0
s3transfer==0.5.2
six==1.17.0
toml @ file:///tmp/build/80754af9/toml_1616166611790/work
tomli==1.2.3
tox==3.28.0
typing_extensions @ file:///opt/conda/conda-bld/typing_extensions_1647553014482/work
uritemplate==4.1.1
urllib3==1.26.20
virtualenv==20.17.1
zipp @ file:///tmp/build/80754af9/zipp_1633618647012/work

name: mapbox-sdk-py
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=21.4.0=pyhd3eb1b0_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - importlib_metadata=4.8.1=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - more-itertools=8.12.0=pyhd3eb1b0_0
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=21.3=pyhd3eb1b0_0
  - pip=21.2.2=py36h06a4308_0
  - pluggy=0.13.1=py36h06a4308_0
  - py=1.11.0=pyhd3eb1b0_0
  - pyparsing=3.0.4=pyhd3eb1b0_0
  - pytest=6.2.4=py36h06a4308_2
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - toml=0.10.2=pyhd3eb1b0_0
  - typing_extensions=4.1.1=pyh06a4308_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.6.0=pyhd3eb1b0_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - boto3==1.23.10
      - botocore==1.26.10
      - cachecontrol==0.12.14
      - charset-normalizer==2.0.12
      - coverage==6.2
      - coveralls==3.3.1
      - distlib==0.3.9
      - docopt==0.6.2
      - filelock==3.4.1
      - idna==3.10
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iso3166==2.1.1
      - jmespath==0.10.0
      - msgpack==1.0.5
      - platformdirs==2.4.0
      - polyline==1.4.0
      - pytest-cov==4.0.0
      - python-dateutil==2.9.0.post0
      - requests==2.27.1
      - responses==0.17.0
      - s3transfer==0.5.2
      - six==1.17.0
      - tomli==1.2.3
      - tox==3.28.0
      - uritemplate==4.1.1
      - urllib3==1.26.20
      - virtualenv==20.17.1
prefix: /opt/conda/envs/mapbox-sdk-py

tests/test_encoding.py::test_encode_waypoints_rounding
tests/test_directions.py::test_class_attrs tests/test_directions.py::test_directions[None] tests/test_directions.py::test_directions[cache1] tests/test_directions.py::test_directions_geojson tests/test_directions.py::test_directions_geojson_as_geojson tests/test_directions.py::test_invalid_profile tests/test_directions.py::test_direction_params tests/test_directions.py::test_direction_backwards_compat tests/test_directions.py::test_direction_bearings tests/test_directions.py::test_direction_bearings_none tests/test_directions.py::test_invalid_geom_encoding tests/test_directions.py::test_v4_profile_aliases tests/test_directions.py::test_invalid_annotations tests/test_directions.py::test_invalid_geom_overview tests/test_directions.py::test_invalid_radiuses tests/test_directions.py::test_invalid_number_of_bearings tests/test_directions.py::test_invalid_bearing_tuple tests/test_directions.py::test_snapping_bearing_none tests/test_directions.py::test_snapping_radii_none tests/test_directions.py::test_validate_radius_none tests/test_directions.py::test_validate_radius_unlimited tests/test_directions.py::test_validate_radius_invalid tests/test_directions.py::test_invalid_bearing_domain tests/test_directions.py::test_bearings_without_radius tests/test_directions.py::test_validate_snapping tests/test_encoding.py::test_read_geojson_features tests/test_encoding.py::test_geo_interface tests/test_encoding.py::test_encode_waypoints tests/test_encoding.py::test_encode_limits tests/test_encoding.py::test_unsupported_geometry tests/test_encoding.py::test_unknown_object tests/test_encoding.py::test_encode_polyline tests/test_encoding.py::test_encode_coordinates_json
mapbox/__init__.py mapbox/services/directions.py mapbox/encoding.py CHANGES mapbox/compat.py
mapbox/__init__.py mapbox/services/directions.py mapbox/encoding.py CHANGES mapbox/compat.py