Skip to content

Commit

Permalink
wip - python 3 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
maffoo committed Dec 20, 2016
1 parent e0cb642 commit f9b6499
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 31 deletions.
5 changes: 3 additions & 2 deletions labrad/auth.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import absolute_import

import getpass
from builtins import input

from labrad import constants

Expand Down Expand Up @@ -77,8 +78,8 @@ def get_username_and_password(host, port, prompt=True):
break
return passwords[user]
elif prompt:
user = raw_input('Enter username, or blank for the global user '
'({}:{}): '.format(host, port))
user = input('Enter username, or blank for the global user '
'({}:{}): '.format(host, port))
password = _prompt_for_password(host, port, user)
return Password(user, password)
else:
Expand Down
14 changes: 5 additions & 9 deletions labrad/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@
from labrad.support import (mangle, indent, PrettyMultiDict, FlatPacket,
PacketRecord, PacketResponse, hexdump)

class NotFoundError(Error):
code = 10
def __init__(self, key):
self.msg = 'Could not find "%s".' % key

def unwrap(s, after='|'):
def trim(line):
Expand Down Expand Up @@ -140,10 +136,7 @@ def __getitem__(self, key):
# force refresh and try again
if self._parent:
self._parent.refresh(now=True)
try:
return super(DynamicAttrDict, self).__getitem__(key)
except KeyError:
raise NotFoundError(key)
return super(DynamicAttrDict, self).__getitem__(key)


class HasDynamicAttrs(object):
Expand Down Expand Up @@ -243,7 +236,10 @@ def __dir__(self):
return sorted(set(self._attrs.keys() + self.__dict__.keys() + dir(type(self))))

def __getattr__(self, key):
return self._attrs[key]
try:
return self._attrs[key]
except KeyError:
raise AttributeError(key)

def __getitem__(self, key):
return self._attrs[key]
Expand Down
5 changes: 3 additions & 2 deletions labrad/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import time
import urllib
import webbrowser
from builtins import input

import requests
from concurrent import futures
Expand Down Expand Up @@ -122,8 +123,8 @@ def do_headless_login():
login_uri = _create_login_uri(client_id, redirect_uri)
print('To obtain an OAuth authorization code, please navigate to the '
'following URL in a browser:\n\n{}\n'.format(login_uri))
code = raw_input('When you have completed the login flow, enter the '
'code here: ')
code = input('When you have completed the login flow, enter the '
'code here: ')
return redirect_uri, code

if headless:
Expand Down
14 changes: 9 additions & 5 deletions labrad/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@
from __future__ import print_function

import hashlib
from builtins import input

from twisted.internet import reactor, protocol, defer
from twisted.internet.defer import inlineCallbacks, returnValue
from twisted.python import failure, log
import labrad.types as T

import labrad.types as T
from labrad import auth, constants as C, crypto, errors, oauth, support, util
from labrad.stream import packetStream, flattenPacket

Expand All @@ -50,7 +51,7 @@ def __init__(self):
self.request_handler = None
# create a generator to assemble the packets
self.packetStream = packetStream(self.packetReceived, self.endianness)
self.packetStream.next() # start the packet stream
next(self.packetStream) # start the packet stream

self.onDisconnect = util.DeferredSignal()

Expand Down Expand Up @@ -87,7 +88,7 @@ def connectionLost(self, reason):
called, or because of some network error.
"""
self.disconnected = True
for d in self.requests.values():
for d in list(self.requests.values()):
d.errback(Exception('Connection lost.'))
if reason == protocol.connectionDone:
self.onDisconnect.callback(None)
Expand Down Expand Up @@ -429,7 +430,10 @@ def require_secure_connection(auth_type):
# send password response
m = hashlib.md5()
m.update(challenge)
m.update(credential.password)
if isinstance(credential.password, bytes):
m.update(credential.password)
else:
m.update(credential.password.encode('UTF-8'))
try:
resp = yield self._sendManagerRequest(0, m.digest())
except Exception:
Expand Down Expand Up @@ -607,7 +611,7 @@ def ping(p):
print('SHA1 Fingerprint={}'.format(crypto.fingerprint(cert)))
print()
while True:
ans = raw_input(
ans = input(
'Accept server certificate for host "{}"? (accept just '
'this [O]nce; [S]ave and always accept this cert; '
'[R]eject) '.format(host))
Expand Down
10 changes: 5 additions & 5 deletions labrad/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

HEADER_TYPE = T.parseTypeTag('(ww)iww')
PACKET_TYPE = T.parseTypeTag('(ww)iws')
RECORD_TYPE = T.parseTypeTag('wss')
RECORD_TYPE = T.parseTypeTag('wsy')

def packetStream(packetHandler, endianness='>'):
"""A generator that assembles packets.
Accepts a function packetHandler that will be called with four arguments
whenever a packet is completed: source, context, request, records.
"""
buf = ''
buf = b''
while True:
# get packet header (20 bytes)
while len(buf) < 20:
Expand Down Expand Up @@ -52,13 +52,13 @@ def flattenPacket(target, context, request, records, endianness='>'):
data = records
else:
kw = {'endianness': endianness}
data = ''.join(flattenRecord(*rec, **kw) for rec in records)
data = b''.join(flattenRecord(*rec, **kw) for rec in records)
flat = PACKET_TYPE.flatten((context, request, target, data), endianness)
return flat.bytes

def flattenRecords(records, endianness='>'):
kw = {'endianness': endianness}
return ''.join(flattenRecord(*rec, **kw) for rec in records)
return b''.join(flattenRecord(*rec, **kw) for rec in records)

def flattenRecord(ID, data, types=[], endianness='>'):
"""Flatten a piece of data into a record with datatype and property."""
Expand All @@ -67,7 +67,7 @@ def flattenRecord(ID, data, types=[], endianness='>'):
except T.FlatteningError as e:
e.msg = e.msg + "\nSetting ID %s." % (ID,)
raise
flat_record = RECORD_TYPE.flatten((ID, str(flat.tag), str(flat.bytes)),
flat_record = RECORD_TYPE.flatten((ID, str(flat.tag), bytes(flat.bytes)),
endianness)
return flat_record.bytes

2 changes: 1 addition & 1 deletion labrad/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def testDefaultFlatAndBack(self):
# simple types
None,
True, False,
1, -1, 2, -2, 0x7FFFFFFF, -0x80000000, 2**32-1,
1, -1, 2, -2, 0x7FFFFFFF, -0x80000000,
'', 'a', '\x00\x01\x02\x03',
datetime.now(),

Expand Down
13 changes: 10 additions & 3 deletions labrad/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,14 @@ def __width__(self, s, endianness):

def __unflatten__(self, s, endianness):
n = struct.unpack(endianness + 'i', s.get(4))[0]
return s.get(n)
b = s.get(n)
if bytes == str:
return b # in python 2, str and bytes are equivalent
else:
try:
return b.decode('UTF-8')
except UnicodeDecodeError:
return b

def __flatten__(self, s, endianness):
if isinstance(s, bytes):
Expand Down Expand Up @@ -718,13 +725,13 @@ def __unflatten__(self, s, endianness):
return s.get(n)

def __flatten__(self, s, endianness):
if not isinstance(s, str):
if not isinstance(s, bytes):
raise FlatteningError(s, self)
return struct.pack(endianness + 'I', len(s)) + s, self

# bytes is an alias for str in python 2.7, but in python 3 they are different.
if bytes != str:
registerType(bytes, LRBytes)
registerType(bytes, LRBytes())

def timeOffset():
now = time.time()
Expand Down
4 changes: 2 additions & 2 deletions labrad/util/hydrant.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from __future__ import print_function

from builtins import range
from builtins import input, range
from datetime import datetime, timedelta
from random import choice, randint, gauss

Expand Down Expand Up @@ -148,4 +148,4 @@ def hoseDataVault(dv, n=1000, silent=True):
print('Success!')
finally:
print('press <enter> to finish...')
raw_input()
input()
11 changes: 9 additions & 2 deletions labrad/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
from __future__ import print_function

import functools
from types import MethodType
try:
from types import UnboundMethodType
except ImportError:
UnboundMethodType = None

from twisted.internet import defer
from twisted.internet.defer import inlineCallbacks, returnValue
Expand Down Expand Up @@ -135,7 +138,11 @@ def wrapped(self, *args, **kw):
self._packet.append(rec)
return self
wrapped.name = setting.name
method = MethodType(wrapped, None, cls)
if UnboundMethodType is not None:
method = UnboundMethodType(wrapped, None, cls)
else:
# in python 3, unbound methods are just functions
method = wrapped
cls._cache[setting.name] = method
cls.settings[setting.name, setting._py_name, setting.ID] = method
setattr(cls, setting._py_name, method)
Expand Down

0 comments on commit f9b6499

Please sign in to comment.