-
Notifications
You must be signed in to change notification settings - Fork 367
Python 3 compatibility #109
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
base: master
Are you sure you want to change the base?
Changes from all commits
a1e5d63
a4ef006
2db4b81
1fc0bd6
dcd62bc
e78bd9a
b22f61f
5e85385
7ae6ec3
6d63385
f38416d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from __future__ import print_function | ||
import midi | ||
pattern = midi.read_midifile("example.mid") | ||
print pattern | ||
print(pattern) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,16 @@ | ||
#!/usr/bin/env python | ||
from __future__ import print_function | ||
|
||
""" | ||
Print a description of a MIDI file. | ||
""" | ||
import midi | ||
import sys | ||
|
||
if len(sys.argv) != 2: | ||
print "Usage: {0} <midifile>".format(sys.argv[0]) | ||
print("Usage: {0} <midifile>".format(sys.argv[0])) | ||
sys.exit(2) | ||
|
||
midifile = sys.argv[1] | ||
pattern = midi.read_midifile(midifile) | ||
print repr(pattern) | ||
print(repr(pattern)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
from containers import * | ||
from events import * | ||
from struct import unpack, pack | ||
from util import * | ||
from fileio import * | ||
|
||
from .containers import * | ||
from .events import * | ||
from .util import * | ||
from .fileio import * |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import math | ||
from future.utils import with_metaclass | ||
|
||
class EventRegistry(object): | ||
Events = {} | ||
|
@@ -15,21 +16,22 @@ def register_event(cls, event, bases): | |
"Event %s already registered" % event.name | ||
cls.MetaEvents[event.metacommand] = event | ||
else: | ||
raise ValueError, "Unknown bases class in event type: "+event.name | ||
raise ValueError("Unknown bases class in event type: ", event.name) | ||
register_event = classmethod(register_event) | ||
|
||
|
||
class AbstractEvent(object): | ||
class RegisterEventMeta(type): | ||
def __init__(cls, name, bases, dict): | ||
if name not in ['AbstractEvent', 'Event', 'MetaEvent', 'NoteEvent', | ||
'MetaEventWithText']: | ||
EventRegistry.register_event(cls, bases) | ||
|
||
class AbstractEvent(with_metaclass(RegisterEventMeta,object)): | ||
__slots__ = ['tick', 'data'] | ||
name = "Generic MIDI Event" | ||
length = 0 | ||
statusmsg = 0x0 | ||
|
||
class __metaclass__(type): | ||
def __init__(cls, name, bases, dict): | ||
if name not in ['AbstractEvent', 'Event', 'MetaEvent', 'NoteEvent', | ||
'MetaEventWithText']: | ||
EventRegistry.register_event(cls, bases) | ||
|
||
def __init__(self, **kw): | ||
if type(self.length) == int: | ||
|
@@ -41,10 +43,18 @@ def __init__(self, **kw): | |
for key in kw: | ||
setattr(self, key, kw[key]) | ||
|
||
def __cmp__(self, other): | ||
if self.tick < other.tick: return -1 | ||
elif self.tick > other.tick: return 1 | ||
return cmp(self.data, other.data) | ||
def __lt__(self, other): | ||
if self.tick < other.tick: | ||
return True | ||
return self.data < other.data | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should be defining all six rich comparison operators, or using the |
||
|
||
def __eq__(self, other): | ||
return (self.__class__ is other.__class__ and | ||
self.tick == other.tick and | ||
self.data == other.data) | ||
|
||
def __ne__(self, other): | ||
return not self.__eq__(other) | ||
|
||
def __baserepr__(self, keys=[]): | ||
keys = ['tick'] + keys + ['data'] | ||
|
@@ -75,10 +85,14 @@ def copy(self, **kw): | |
_kw.update(kw) | ||
return self.__class__(**_kw) | ||
|
||
def __cmp__(self, other): | ||
if self.tick < other.tick: return -1 | ||
elif self.tick > other.tick: return 1 | ||
return 0 | ||
def __lt__(self, other): | ||
return (super(Event, self).__lt__(other) or | ||
(super(Event, self).__eq__(other) and | ||
self.channel < other.channel)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This changes the logic instead of just porting to Python 3. Intentional? (Also, see above re: functools.total_ordering) |
||
|
||
def __eq__(self, other): | ||
return super(Event, self).__eq__(other) and \ | ||
self.channel == other.channel | ||
|
||
def __repr__(self): | ||
return self.__baserepr__(['channel']) | ||
|
@@ -111,7 +125,6 @@ def is_event(cls, statusmsg): | |
""" | ||
|
||
class NoteEvent(Event): | ||
__slots__ = ['pitch', 'velocity'] | ||
length = 2 | ||
|
||
def get_pitch(self): | ||
|
@@ -152,7 +165,6 @@ def set_value(self, val): | |
value = property(get_value, set_value) | ||
|
||
class ControlChangeEvent(Event): | ||
__slots__ = ['control', 'value'] | ||
statusmsg = 0xB0 | ||
length = 2 | ||
name = 'Control Change' | ||
|
@@ -170,7 +182,6 @@ def get_value(self): | |
value = property(get_value, set_value) | ||
|
||
class ProgramChangeEvent(Event): | ||
__slots__ = ['value'] | ||
statusmsg = 0xC0 | ||
length = 1 | ||
name = 'Program Change' | ||
|
@@ -182,7 +193,6 @@ def get_value(self): | |
value = property(get_value, set_value) | ||
|
||
class ChannelAfterTouchEvent(Event): | ||
__slots__ = ['value'] | ||
statusmsg = 0xD0 | ||
length = 1 | ||
name = 'Channel After Touch' | ||
|
@@ -194,7 +204,6 @@ def get_value(self): | |
value = property(get_value, set_value) | ||
|
||
class PitchWheelEvent(Event): | ||
__slots__ = ['pitch'] | ||
statusmsg = 0xE0 | ||
length = 2 | ||
name = 'Pitch Wheel' | ||
|
@@ -302,7 +311,6 @@ class EndOfTrackEvent(MetaEvent): | |
metacommand = 0x2F | ||
|
||
class SetTempoEvent(MetaEvent): | ||
__slots__ = ['bpm', 'mpqn'] | ||
name = 'Set Tempo' | ||
metacommand = 0x51 | ||
length = 3 | ||
|
@@ -315,7 +323,7 @@ def get_bpm(self): | |
|
||
def get_mpqn(self): | ||
assert(len(self.data) == 3) | ||
vals = [self.data[x] << (16 - (8 * x)) for x in xrange(3)] | ||
vals = [self.data[x] << (16 - (8 * x)) for x in range(3)] | ||
return sum(vals) | ||
def set_mpqn(self, val): | ||
self.data = [(val >> (16 - (8 * x)) & 0xFF) for x in range(3)] | ||
|
@@ -326,7 +334,6 @@ class SmpteOffsetEvent(MetaEvent): | |
metacommand = 0x54 | ||
|
||
class TimeSignatureEvent(MetaEvent): | ||
__slots__ = ['numerator', 'denominator', 'metronome', 'thirtyseconds'] | ||
name = 'Time Signature' | ||
metacommand = 0x58 | ||
length = 4 | ||
|
@@ -356,7 +363,6 @@ def set_thirtyseconds(self, val): | |
thirtyseconds = property(get_thirtyseconds, set_thirtyseconds) | ||
|
||
class KeySignatureEvent(MetaEvent): | ||
__slots__ = ['alternatives', 'minor'] | ||
name = 'Key Signature' | ||
metacommand = 0x59 | ||
length = 2 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally would be inclined to use
six
instead offuture
-- it seems less intrusive. Although the actualwith_metaclass
implementation is just 8 lines of code, so maybe just copy it here to avoid dealing with extra dependencies?