Skip to content

Ran black, updated to pylint 2.x #74

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

Merged
merged 2 commits into from
Mar 17, 2020
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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
source actions-ci/install.sh
- name: Pip install pylint, black, & Sphinx
run: |
pip install --force-reinstall pylint==1.9.2 black==19.10b0 Sphinx sphinx-rtd-theme
pip install --force-reinstall pylint black==19.10b0 Sphinx sphinx-rtd-theme
- name: Library version
run: git describe --dirty --always --tags
- name: PyLint
Expand Down
54 changes: 39 additions & 15 deletions adafruit_ble/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@
building on the native `_bleio` module.

"""
#pylint: disable=wrong-import-position
# pylint: disable=wrong-import-position
import sys
if sys.implementation.name == 'circuitpython' and sys.implementation.version[0] <= 4:

if sys.implementation.name == "circuitpython" and sys.implementation.version[0] <= 4:
raise ImportError(
"This release is not compatible with CircuitPython 4.x; use library release 1.x.x")
#pylint: enable=wrong-import-position
"This release is not compatible with CircuitPython 4.x; use library release 1.x.x"
)
# pylint: enable=wrong-import-position

import _bleio

Expand All @@ -41,6 +43,7 @@
__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_BLE.git"


class BLEConnection:
"""
Represents a connection to a peer BLE device.
Expand All @@ -49,6 +52,7 @@ class BLEConnection:
:param bleio_connection _bleio.Connection: the native `_bleio.Connection` object to wrap

"""

def __init__(self, bleio_connection):
self._bleio_connection = bleio_connection
# _bleio.Service objects representing services found during discovery.
Expand All @@ -61,7 +65,9 @@ def _discover_remote(self, uuid):
if uuid in self._discovered_bleio_services:
remote_service = self._discovered_bleio_services[uuid]
else:
results = self._bleio_connection.discover_remote_services((uuid.bleio_uuid,))
results = self._bleio_connection.discover_remote_services(
(uuid.bleio_uuid,)
)
if results:
remote_service = results[0]
self._discovered_bleio_services[uuid] = remote_service
Expand Down Expand Up @@ -140,6 +146,7 @@ def disconnect(self):
"""Disconnect from peer."""
self._bleio_connection.disconnect()


class BLERadio:
"""
BLERadio provides the interfaces for BLE advertising,
Expand Down Expand Up @@ -172,17 +179,28 @@ def start_advertising(self, advertisement, scan_response=None, interval=0.1):
scan_response.tx_power = self.tx_power
if scan_response:
scan_response_bytes = bytes(scan_response)
self._adapter.start_advertising(advertisement_bytes,
scan_response=scan_response_bytes,
connectable=advertisement.connectable,
interval=interval)
self._adapter.start_advertising(
advertisement_bytes,
scan_response=scan_response_bytes,
connectable=advertisement.connectable,
interval=interval,
)

def stop_advertising(self):
"""Stops advertising."""
self._adapter.stop_advertising()

def start_scan(self, *advertisement_types, buffer_size=512, extended=False, timeout=None,
interval=0.1, window=0.1, minimum_rssi=-80, active=True):
def start_scan(
self,
*advertisement_types,
buffer_size=512,
extended=False,
timeout=None,
interval=0.1,
window=0.1,
minimum_rssi=-80,
active=True
):
"""
Starts scanning. Returns an iterator of advertisement objects of the types given in
advertisement_types. The iterator will block until an advertisement is heard or the scan
Expand Down Expand Up @@ -214,10 +232,16 @@ def start_scan(self, *advertisement_types, buffer_size=512, extended=False, time
prefixes = b""
if advertisement_types:
prefixes = b"".join(adv.prefix for adv in advertisement_types)
for entry in self._adapter.start_scan(prefixes=prefixes, buffer_size=buffer_size,
extended=extended, timeout=timeout,
interval=interval, window=window,
minimum_rssi=minimum_rssi, active=active):
for entry in self._adapter.start_scan(
prefixes=prefixes,
buffer_size=buffer_size,
extended=extended,
timeout=timeout,
interval=interval,
window=window,
minimum_rssi=minimum_rssi,
active=active,
):
adv_type = Advertisement
for possible_type in advertisement_types:
if possible_type.matches(entry) and issubclass(possible_type, adv_type):
Expand Down
39 changes: 30 additions & 9 deletions adafruit_ble/advertising/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@

import struct


def to_hex(seq):
"""Pretty prints a byte sequence as hex values."""
return " ".join("{:02x}".format(v) for v in seq)


def to_bytes_literal(seq):
"""Prints a byte sequence as a Python bytes literal that only uses hex encoding."""
return "b\"" + "".join("\\x{:02x}".format(v) for v in seq) + "\""
return 'b"' + "".join("\\x{:02x}".format(v) for v in seq) + '"'


def decode_data(data, *, key_encoding="B"):
"""Helper which decodes length encoded structures into a dictionary with the given key
Expand All @@ -45,7 +48,7 @@ def decode_data(data, *, key_encoding="B"):
if item_length == 0:
break
key = struct.unpack_from(key_encoding, data, i)[0]
value = data[i + key_size:i + item_length]
value = data[i + key_size : i + item_length]
if key in data_dict:
if not isinstance(data_dict[key], list):
data_dict[key] = [data_dict[key]]
Expand All @@ -55,6 +58,7 @@ def decode_data(data, *, key_encoding="B"):
i += item_length
return data_dict


def compute_length(data_dict, *, key_encoding="B"):
"""Computes the length of the encoded data dictionary."""
value_size = 0
Expand All @@ -66,6 +70,7 @@ def compute_length(data_dict, *, key_encoding="B"):
value_size += len(value)
return len(data_dict) + len(data_dict) * struct.calcsize(key_encoding) + value_size


def encode_data(data_dict, *, key_encoding="B"):
"""Helper which encodes dictionaries into length encoded structures with the given key
encoding."""
Expand All @@ -79,17 +84,21 @@ def encode_data(data_dict, *, key_encoding="B"):
item_length = key_size + len(value)
struct.pack_into("B", data, i, item_length)
struct.pack_into(key_encoding, data, i + 1, key)
data[i + 1 + key_size: i + 1 + item_length] = bytes(value)
data[i + 1 + key_size : i + 1 + item_length] = bytes(value)
i += 1 + item_length
return data


class AdvertisingDataField:
"""Top level class for any descriptor classes that live in Advertisement or its subclasses."""

# pylint: disable=too-few-public-methods,unnecessary-pass
pass


class AdvertisingFlag:
"""A single bit flag within an AdvertisingFlags object."""

def __init__(self, bit_position):
self._bitmask = 1 << bit_position

Expand All @@ -102,6 +111,7 @@ def __set__(self, obj, value):
else:
obj.flags &= ~self._bitmask


class AdvertisingFlags(AdvertisingDataField):
"""Standard advertising flags"""

Expand Down Expand Up @@ -135,10 +145,12 @@ def __str__(self):
parts.append(attr)
return "<AdvertisingFlags {} >".format(" ".join(parts))


class String(AdvertisingDataField):
"""UTF-8 encoded string in an Advertisement.

Not null terminated once encoded because length is always transmitted."""

def __init__(self, *, advertising_data_type):
self._adt = advertising_data_type

Expand All @@ -152,8 +164,10 @@ def __get__(self, obj, cls):
def __set__(self, obj, value):
obj.data_dict[self._adt] = value.encode("utf-8")


class Struct(AdvertisingDataField):
"""`struct` encoded data in an Advertisement."""

def __init__(self, struct_format, *, advertising_data_type):
self._format = struct_format
self._adt = advertising_data_type
Expand All @@ -171,6 +185,7 @@ def __set__(self, obj, value):

class LazyObjectField(AdvertisingDataField):
"""Non-data descriptor useful for lazily binding a complex object to an advertisement object."""

def __init__(self, cls, attribute_name, *, advertising_data_type, **kwargs):
self._cls = cls
self._attribute_name = attribute_name
Expand All @@ -197,15 +212,17 @@ def advertising_data_type(self):
# TODO: Add __set_name__ support to CircuitPython so that we automatically tell the descriptor
# instance the attribute name it has and the class it is on.


class Advertisement:
"""Core Advertisement type"""
prefix = b"\x00" # This is an empty prefix and will match everything.

prefix = b"\x00" # This is an empty prefix and will match everything.
flags = LazyObjectField(AdvertisingFlags, "flags", advertising_data_type=0x01)
short_name = String(advertising_data_type=0x08)
"""Short local device name (shortened to fit)."""
complete_name = String(advertising_data_type=0x09)
"""Complete local device name."""
tx_power = Struct("<b", advertising_data_type=0x0a)
tx_power = Struct("<b", advertising_data_type=0x0A)
"""Transmit power level"""
# DEVICE_ID = 0x10
# """Device identifier."""
Expand Down Expand Up @@ -242,7 +259,7 @@ def from_entry(cls, entry):
self = cls()
self.data_dict = decode_data(entry.advertisement_bytes)
self.address = entry.address
self._rssi = entry.rssi # pylint: disable=protected-access
self._rssi = entry.rssi # pylint: disable=protected-access
self.connectable = entry.connectable
self.scan_response = entry.scan_response
self.mutable = False
Expand Down Expand Up @@ -272,8 +289,10 @@ def __str__(self):
for attr in dir(self.__class__):
attribute_instance = getattr(self.__class__, attr)
if issubclass(attribute_instance.__class__, AdvertisingDataField):
if (issubclass(attribute_instance.__class__, LazyObjectField) and
not attribute_instance.advertising_data_type in self.data_dict):
if (
issubclass(attribute_instance.__class__, LazyObjectField)
and not attribute_instance.advertising_data_type in self.data_dict
):
# Skip uninstantiated lazy objects; if we get
# their value, they will be be instantiated.
continue
Expand All @@ -286,4 +305,6 @@ def __len__(self):
return compute_length(self.data_dict)

def __repr__(self):
return "Advertisement(data={})".format(to_bytes_literal(encode_data(self.data_dict)))
return "Advertisement(data={})".format(
to_bytes_literal(encode_data(self.data_dict))
)
29 changes: 17 additions & 12 deletions adafruit_ble/advertising/adafruit.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,29 @@
__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_BLE.git"

_MANUFACTURING_DATA_ADT = const(0xff)
_MANUFACTURING_DATA_ADT = const(0xFF)
_ADAFRUIT_COMPANY_ID = const(0x0822)
_COLOR_DATA_ID = const(0x0000)


class AdafruitColor(Advertisement):
"""Broadcast a single RGB color."""

# This prefix matches all
prefix = struct.pack("<BBHBH",
0x6,
_MANUFACTURING_DATA_ADT,
_ADAFRUIT_COMPANY_ID,
struct.calcsize("<HI"),
_COLOR_DATA_ID)
manufacturer_data = LazyObjectField(ManufacturerData,
"manufacturer_data",
advertising_data_type=_MANUFACTURING_DATA_ADT,
company_id=_ADAFRUIT_COMPANY_ID,
key_encoding="<H")
prefix = struct.pack(
"<BBHBH",
0x6,
_MANUFACTURING_DATA_ADT,
_ADAFRUIT_COMPANY_ID,
struct.calcsize("<HI"),
_COLOR_DATA_ID,
)
manufacturer_data = LazyObjectField(
ManufacturerData,
"manufacturer_data",
advertising_data_type=_MANUFACTURING_DATA_ADT,
company_id=_ADAFRUIT_COMPANY_ID,
key_encoding="<H",
)
color = ManufacturerDataField(_COLOR_DATA_ID, "<I")
"""Color to broadcast as RGB integer."""
Loading