dhamaniasad / mutagen

Automatically exported from code.google.com/p/mutagen
GNU General Public License v2.0
2 stars 1 forks source link

Python 3.0 Support #27

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Not really an issue, but it would really be great to seee suppor for Python
3.0.  Or is there support and I'm too n00b to figure out how to work it?  

Original issue reported on code.google.com by hypergee...@gmail.com on 23 Sep 2009 at 11:03

GoogleCodeExporter commented 9 years ago
There's no Python 3 support.

We'd basically need another maintainer for a Python 3 version who would have to 
do
most of the porting by hand, since I'm not interested in doing it (Python 3 is 
shit),
and 2to3 also falls flat on its face trying to convert Mutagen.

Original comment by joe.wreschnig@gmail.com on 28 Sep 2009 at 4:34

GoogleCodeExporter commented 9 years ago
Sounds fine.  

I'm not into python enough to know why 3 is worse than 2 (I just downloaded it
because it was newer of course.)  But I trust your experience, so I'll switch 
back. 
The only difference I can notice is that 'print' is a function now and not a
statement (Hope those are the right terms.)  Plus I want to use mutagen, so I 
have to
go back.  

Original comment by hypergee...@gmail.com on 28 Sep 2009 at 8:36

GoogleCodeExporter commented 9 years ago
Python 3 is meant to be faster but since it's new... The code for it will 
change over
time. I tried doing a 2 to 3 for Musicbrainz Picard. Broke the code fully. :P 
Wud be
good to have Python 3 support at some point tho, when everyone else decides to 
switch
over.

Original comment by opensh...@gmail.com on 1 Oct 2009 at 8:29

GoogleCodeExporter commented 9 years ago
Hi

I have done preliminary porting to get this to work under python 3.1. 
Basically, the
install works and I'm assuming that the following hold true:

1) since all strings in python 3.1 are supposed to be utf, the preceding 'u' 
for a
string declaration isn't required -- I've removed them
2) since the short and long int have been unified, the trailing 'L' for a long 
int
should be unnecessary -- so I've dropped them.
3) Python 3.1 doesn't seem to like tuple variables in function declarations -- 
or,
rather, doesn't provide the syntactic sugar of automatically expanding them 
into the
named variables. For example, the following definition is no longer valid:
def __key_sort((key1, v1), (key2, v2)):
I've replaced the only occurrences of this with boilerplate code to check if the
variables sent in are tuples with minimum length 2 and then expanded the tuples 
out
into variables of the same names (key1, v1, key2, v2). Since this happens in 
code
that I don't really traverse, I would appreciate feedback.
4) I've replaced all exception handling which used the comma-notation with the 
more
functional-style notation (which works just fine under py2.6), so, for example:
except Exception, e:
is replaced with
except Exception as e
and
raise Exception, "foo to the bar"
is replaced with
raise Exception("foo to the bar")

The problem with (1) and (2) is that I can't seem to put them in try blocks or
equivalent -- basically, they have to be "as-is" in the code, which I'm 
assuming will
break 2.6 usage, since I'm assuming the original author put them in there for a 
reason.

I would appreciate it if anyone interested (in particular, the mutagen author, 
Joe
Wreschnig, without whose excellent code, fappy (also to be found on google code)
would not exist) would get back to me. Whilst the transition to py31 is a little
painful from py26 (I've been putting it off for *ages*), it's gonna happen some 
time,
and I have to assume that the py devs have good reasons for breaking backwards
compat. Personally, I want to deploy to as many people as possible, so, where
possible, I just try to write code that works in both. Points (1) and (2) above 
are
sticky wrt cross-interpreter code, but I'm open for suggestions. I don't 
believe that
3.1-specific or 2.6-specific code is "the way to go" -- rather, let's try make 
this
rad library work *everywhere*  (:

Original comment by dav...@gmail.com on 18 Feb 2010 at 3:11

Attachments:

GoogleCodeExporter commented 9 years ago
Also, I forgot to add that I use io.StringIO when cStringIO.StringIO can't be 
loaded.

Original comment by dav...@gmail.com on 18 Feb 2010 at 3:12

GoogleCodeExporter commented 9 years ago
gah, ignore me -- there are apparently kinks to work out first. I will beat this
though (:

Original comment by dav...@gmail.com on 18 Feb 2010 at 3:24

GoogleCodeExporter commented 9 years ago
davydm: I haven't looked at your code, but from your description it sounds like
you're trying to port mutagen directly, rather than using the 2to3 tool. The 
best
approach to achieve compatibility with py3k is to use 2to3 to generate the py3k
version automatically. In case 2to3 doesn't produce working code, any 
ambiguities
should be fixed in the 2.x source, not the converted source.

http://docs.python.org/library/2to3.html
http://diveintopython3.org/porting-code-to-python-3-with-2to3.html

Original comment by steven.strobe.cc@gmail.com on 18 Feb 2010 at 7:35

GoogleCodeExporter commented 9 years ago
Because Mutagen actually handles Unicode in complicated but correct ways, 2to3 
crapped 
all over it last time I tried it.

Original comment by joe.wreschnig@gmail.com on 18 Feb 2010 at 8:58

GoogleCodeExporter commented 9 years ago
Yeah, reading the comment about 2to3 versus looking at the actual source (and 
working
through issues as I come across them) makes me think that any conversion script 
is
going to cause more headaches than it solves. Sure, a script could sort out the
changes in syntax for, eg, exception handling or unicode strings being the 
"norm".
But that was a minor part of the deal -- I'm working through problems with when
something should be a bytes() type and when it shouldn't -- as well as how to 
achieve
things where were quite easy in py26 (such as finding the first occurrence of 
"\xff"
in a string of bytes). Where possible, I'm trying to keep the code working for 
both
python 2.x and py3k. Like I said above, I'm not a zealot for either platform -- 
I
just realise that, at some point, there will cease to be a python[N-1] which 
means
that I need to get stuff working on python[N] and mutagen has saved me a lot of
headache and hassle wrt fappy -- if I can overcome the issues that I have on a 
py3k
interpreter (and it just seems that I need more time than I thought: I'm slowly
getting there) then I would gladly contribute them back -- if anyone is 
interested
and my code meets the standards requirements for mutagen code.

Original comment by dav...@gmail.com on 19 Feb 2010 at 8:08

GoogleCodeExporter commented 9 years ago
It's basically impossible to support both reasonably old versions Python 2.x 
and Python 
3 (Google stills run Python 2.4 internally, I believe; "old" but common 
versions of OS 
X still come with 2.4 and 2.5). I think Mutagen still supports 2.3, although I 
have to 
admit I haven't tested it in a while, so 2.4 might be our baseline now.

I have my doubts that Python 2 will cease to exist before, let's say, 2015.

Original comment by joe.wreschnig@gmail.com on 19 Feb 2010 at 7:32

GoogleCodeExporter commented 9 years ago
Hi Davydm, were you able to get Mutagen to work on 3.1?

Original comment by jenmi...@gmail.com on 26 Mar 2010 at 3:41

GoogleCodeExporter commented 9 years ago
Just so no-one is left in the dark: I haven't done much work on mutagen with 
py3k for a while -- I have to admit I was a little defeated when I was about 
90% done and a new version of mutagen came out with quite significant changes 
-- not that I'm complaining (: I just don't want anyone to think I'm holding 
some amazing conversion here where no-one can see it (: I will get back on to 
it at some point -- the urgency has dropped since I've found (imperfect) ways 
to use a locally-installed py26 in preference to py31 on both windows and *nix. 
But I still maintain this is an important step forward -- Mutagen ROCKS and 
py3k has proven itself to, if nothing else, provide significant performance 
boosts in areas where I've used it.

Original comment by dav...@gmail.com on 4 Aug 2010 at 6:30

GoogleCodeExporter commented 9 years ago
My machine still gets 14% more pystones on 2.6 than 3.1. Most of the 
performance improvements are getting backported. Most of the slow things are 
not.

Original comment by joe.wreschnig@gmail.com on 4 Aug 2010 at 8:05

GoogleCodeExporter commented 9 years ago
While 2.x won't cease to exist for a long time, more and more projects are 
going to be written in 3.x as time goes on. I know from personal experience 
that writing code that works _simultaneously_ in both can be quite a headache, 
but making little syntax changes to the existing 2.x code now can make it 
_tons_ easier to port to 3.x later. When looking at the current source, the 
most obvious to me is davydm's #4: There are already places in the source that 
use the constructor method, so why not use it everywhere? It it just a matter 
of when stuff was written? If its just a matter of taking the time to go 
through the entire source and making little syntax adjustments like this, I'd 
be perfectly willing to do so.

Alternate solutions to #1 and 2 (assuming 2to3 doesn't do it satisfactorily) 
are to use explicit constructors like long(100) for 100L and unicode('foo') for 
u'foo'. Then saying
if 'long' not in dir(__builtins__):
  long = int
if 'unicode' not in dir(__builtins__):
  unicode = str
should make everyone happy.

Also, I noticed a few other syntax oddities in the source, like one spot where 
it goes
def score....
score = staticmethod(score)
instead of just saying
@staticmethod
def score....
Is this like this deliberately? or has it just been that way since the dawn of 
time and never changed? Or am I missing something?

I've got a couple of personal projects that could _really_ benefit from seeing 
mutagen work in 3.x, so if there is some way I could contribute these minor 
little syntax tweaks I'd love to. (I'm a total n00b at the whole svn thing, so 
how would I go about possibly joining this project and submitting patches? Or 
should I just make the changes and post it in a tarball here?)

Original comment by nerdywhi...@gmail.com on 20 Aug 2010 at 10:08

GoogleCodeExporter commented 9 years ago
Absolutely do not just post a tarball; those make it nearly impossible to see 
what changed. Instead follow the instructions on the Source tab to check out 
mutagen into some directory. Then make all your changes. Then in the root 
directory, run `svn diff > my.patch` to generate a patch.

Original comment by mur...@gmail.com on 20 Aug 2010 at 1:37

GoogleCodeExporter commented 9 years ago
nerdywhiteguy, nearly everything you describe (new exception syntax, decorator 
use) is what 2to3 does. That's not the hard part. What's hard is making sure 
everything is still correct. I haven't downloaded the tarball to check 
(because, well, it's a tarball rather than a patch) but I find it very unlikely 
that our test suite comes anywhere close to passing.

Mutagen uses "old" Python constructs because it is an "old" Python program 
written by even "older" Python programmers. There's no point in churning code 
for that kind of stuff.

Also, I still don't see 3.x being relevant. Frankly I still have hope it will 
get over itself and die already. If I were you, I'd rewrite your projects to 
support 2.x. There's zero downside to supporting it.

Original comment by joe.wreschnig@gmail.com on 20 Aug 2010 at 8:36

GoogleCodeExporter commented 9 years ago
99% of my code would work fine in 2.x. The problem is the 1% that doesn't, 
because those are often pivotal points of the program. One of the biggest 
examples is keyword-only arguments to functions. I don't use them very much, 
but in the few places I do, its absolutely critical that I do.

A good example is a class of mine that takes an arbitrary number of 
arbitrary-typed arguments, as well as an optional boolean flag. You can't trim 
the last entry from args if its a boolean, because args could be intended to 
contain booleans and the flag intended to be unset. A keyword-only arg is the 
only solution, as far as I'm aware. Feel free to prove me wrong though. :P

If they were to back-port support for keyword-only args (since regular args 
work the same as always, so it wouldn't break old code), I'd keep using 2.x as 
well, since lots of the new features are indeed being backported.

Another difference I noticed is that in 2.x,
[b for c in d]
will result in the variable c floating around in the local scope, while this 
doesn't happen in 3.x.
I discovered this when mutagen/_util.py threw a NameError at me after some 
clean-up code tried to del two variables that it didn't have to.

Woah. I see what you mean, davydm: There are TONS of places where there are 
errors due to mix-ups between str and bytes. Like assertions that fail because 
'a' != b'a', and the like. I did notice that str.encode/decode work in 2.x, so 
perhaps putting in a lot of those in the 2.x source and running it through 2to3 
again will help solve some problems.

Ideally, a quick shot through 2to3 should yield runable code, so that will be 
my goal.

Original comment by nerdywhi...@gmail.com on 20 Aug 2010 at 10:30

GoogleCodeExporter commented 9 years ago
The following works fine in Python 2.x. It might be considered not as clean. On 
the other hand, it's a pretty dumb feature to rewrite your entire language for.

def foo(*args, **kwargs):
    my_bool = kwargs.pop("stupid_special_flag", False)
    assert(not kwargs)

Original comment by joe.wreschnig@gmail.com on 21 Aug 2010 at 5:14

GoogleCodeExporter commented 9 years ago
If no one is working on this, I'm going to close it as WontFix. Python 3 
remains dead to me.

Original comment by joe.wreschnig@gmail.com on 12 Dec 2010 at 9:16

GoogleCodeExporter commented 9 years ago
I'm kinda working on it on and off.
There are a freaking million bytes vs string vs the old unicde errors.
And then there are more subtle errors.
And then I get annoyed with it and go do something else for a while. :P

But do you really plan to stay with Python 2 forever?

Original comment by nerdywhi...@gmail.com on 12 Dec 2010 at 9:24

GoogleCodeExporter commented 9 years ago
Do you really find serious value in Python 3? I mean something that really 
helps you program better, not that philosophically speaking, variables first 
bound within expressions should not leak to the enclosing local scope.

Original comment by joe.wreschnig@gmail.com on 12 Dec 2010 at 9:55

GoogleCodeExporter commented 9 years ago
I have a slightly revised request:  can you at least update it so that running 
it with the "-3" flag (under 2.6 or later) doesn't issue deprecation warnings?  
Some day Python 3 will probably take over, so I use the -3 flag to keep myself 
from getting into habits that I'll have to break later.

The particular warnings I get when I import mutagen are:
mutagen/id3.py:763: DeprecationWarning: Overriding __cmp__ blocks inheritance 
of __hash__ in 3.x
  class ID3TimeStamp(object):
mutagen/id3.py:1125: DeprecationWarning: Overriding __eq__ blocks inheritance 
of __hash__ in 3.x
  class TextFrame(Frame):
(lots of the above two, for various classes)
and
mutagen/flac.py:38: DeprecationWarning: reduce() not supported in 3.x; use 
functools.reduce()

Both are very easy to tweak in a 2.x-compatible way that will leave you (and 
others) in a better position to port to 3.x some day.

Original comment by pjcre...@gmail.com on 4 Jan 2011 at 12:24

GoogleCodeExporter commented 9 years ago
Patches for such concerns will be applied if they're not crap; issue 74 already 
contained one. Mutagen still tries to target Python 2.3, so keep that in mind 
when writing patches.

Original comment by joe.wreschnig@gmail.com on 4 Jan 2011 at 1:35

GoogleCodeExporter commented 9 years ago
Here's an initial patch, based on 1.20.  This patch was tested by running 
"python -3 setup.py test".  Before patch, it produced 55 warnings.  After, it 
produces none.

Notes:

1) I assumed that you wanted no change in behavior, so all the explicit 
__hash__ functions simply inherit from the parent class (as they do by default 
in Python 2.x).  There may be some of these classes for which you want to 
harmonize __hash__ with __cmp__/__eq__, but that would change the functionality.

2) The import of the "sets" module in test_id3.py appeared to have no purpose, 
so I removed it.  If you'd rather preserve it, I can easily wrap it inside a 
test for Python version.

3) Some deprecation warnings may not appear until code is exercised, so I may 
not have caught all of the warnings.  For example, the functools.reduce() 
warning mentioned in my initial report doesn't get triggered by the the test 
suite.  I caught it in my usage:

    import mutagen.flac
    f = mutagen.File("foo.flac")  # triggers functools.reduce warning

I suspect that means this code isn't getting tested by the test suite.  I'm not 
sure what tests would be appropriate.

Original comment by pjcre...@gmail.com on 17 Jan 2011 at 2:28

Attachments:

GoogleCodeExporter commented 9 years ago
If you run ./setup.py coverage it will generate a coverage report of the test 
suite. I am not sure why the warning didn't trigger for you, because the reduce 
call in mutagen.flac is reached 29,990 times during the test suite according to 
my report.

Original comment by joe.wreschnig@gmail.com on 18 Jan 2011 at 10:41

GoogleCodeExporter commented 9 years ago
Your patch seems to add __hash__ to some things that did not have it before, 
thus making them hashable. Why?

For example, DictMixin and ID3TimeStamp both have comparison methods, but not 
__hash__, which is correct for them, but you gave them object.__hash__. 
Likewise, flac.MetadataBlock said nothing about hashes so subclasses were only 
hashable if they did not define __eq__ or __cmp__; your patch gives several of 
them explicit hashes, making them both mutable and hashable.

Original comment by joe.wreschnig@gmail.com on 18 Jan 2011 at 11:17

GoogleCodeExporter commented 9 years ago
I believe they were hashable before.  All I did was make their existing hashing 
behavior explicit, by inheriting their parent class's __hash__ method (or lack 
thereof).  (For example, id3.Frame subclasses explicitly inherit Frame's 
__hash__ method, which raises a TypeError.)

This was a subtle change that happened with the advent of new-style classes, so 
you may not have been aware of this behavior.  See 
<http://mail.python.org/pipermail/python-bugs-list/2003-February/016089.html> 
and <http://www.mail-archive.com/python-list@python.org/msg116409.html>.

To your example, DictMixIn and ID3TimeStamp were hashable because they 
inherited object's __hash__ method.  (Python 3 changes that behavior, blocking 
the inheritance, which is why the -3 flag produces a warning.)  If your intent 
was for those objects not to be hashable, you could easily make that explicit 
by defining __hash__ to raise a TypeError.

Likewise, flac.MetadataBlock inherited object's __hash__ method, so that it and 
all its subclasses were hashable, regardless of whether they defined __eq__ or 
__cmp__.  Again, if you want the subclasses that define __eq__ or __cmp__ not 
to be hashable, you can explicitly define their __hash__ method to raise a 
TypeError.

A test in 2.4:

>>> class InheritedHash(object):
...     def __eq__(self, other): return self.name == other.name
... 
>>> class Unhashable(object):
...     def __hash__(self): raise TypeError("unhashable object")
... 
>>> class SimpleUnhashable(object):
...     __hash__ = None           
... 
>>> a = InheritedHash()
>>> b = Unhashable()
>>> c = SimpleUnhashable()
>>> d = { a: "whee" }
>>> d = { b: "whee" }
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in __hash__
TypeError: unhashable object
>>> d = { c: "whee" }
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: 'NoneType' object is not callable

Python 2.6 cleans up this last case by producing the following output without 
requiring you to raise a TypeError in all of your classes:

>>> d = { c: "whee" }
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'SimpleUnhashable'

To conclude, I believe my patch introduced no change in behavior, but it seems 
that it uncovered some undesirable implicit behavior, given that these objects 
are mutable.  I'd be happy to submit a revised patch, but you may be best 
suited to determine which objects are intended to be mutable and which are not.

Original comment by pjcre...@gmail.com on 20 Jan 2011 at 2:34

GoogleCodeExporter commented 9 years ago
Indeed, the problem appears to be that I'm too old and remembering 
pre-new-style behavior.

Original comment by joe.wreschnig@gmail.com on 20 Jan 2011 at 8:23

GoogleCodeExporter commented 9 years ago
Well, the good news is that Python 3 reverts to that behavior.  ;)

Let me know if you'd like me to revise my patch in any way.

Original comment by pjcre...@gmail.com on 20 Jan 2011 at 7:02

GoogleCodeExporter commented 9 years ago
I managed to add Python 3 support, but only for mp3 files and id3 headers, so 
it can be done.  Both reading and writing works in the minimal testing I've 
done.

 It's more of a hack than a port, but it works for my current needs.

Original comment by brian.le...@gmail.com on 11 Mar 2011 at 6:37

GoogleCodeExporter commented 9 years ago
I'd just add for anyone else who was looking here for Python 3 support that 
there's a project called "stagger" at http://code.google.com/p/stagger/ which 
appears to work fine.  I'm sure it's nowhere near as complete or robust or 
"well supported" (if you're using Python 2) as this is, but the svn head worked 
for me.

[Maybe it's just me, but comments like "Python 3 is shit" are a pretty big flag 
that at least some people here are not as competent as they think they are.]

Original comment by acooke....@gmail.com on 23 Mar 2011 at 6:03

GoogleCodeExporter commented 9 years ago
Well, I said that a year and a half ago. In the intervening time Python 3 
mostly graduated from "shit" to "irrelevant".

stagger is what you get if you take the core of Mutagen's ID3 parser and 
replace all the trimmings with Python 3.0 era stuff rather than Python 2.3 era 
stuff. It's not bad, and I don't want to degrade Karoly's work, which provides 
useful tools to programmers that need them.

But you, apparently, want to degrade ours. So I think if you're going to 
measure competency, you should look at which module copied the other's 
architecture, and which module provides *tagging* support rather than just 
*ID3* support. And again, go back and look at what, exactly, Python 3 gets you. 
Because it's still basically nothing, in exchange for a whole lot of 
compatibility headache.

Original comment by joe.wreschnig@gmail.com on 23 Mar 2011 at 8:12

GoogleCodeExporter commented 9 years ago
@Brian
Could you upload somewhere patch/working version of this "hack" of yours?

Original comment by kuromo on 11 Nov 2011 at 10:30

GoogleCodeExporter commented 9 years ago
@kuromo

http://dl.dropbox.com/u/1269251/mutagen_2to3.diff

Original comment by brian.le...@gmail.com on 8 Dec 2011 at 2:47

GoogleCodeExporter commented 9 years ago
So whats the status of this library? Soon everything will be ported to Python 
3, I'm currently waiting for Django which will take another 1-3 releases until 
its done as I was told. Do I have to look for a new library?

Original comment by nukeawhale@gmail.com on 13 May 2012 at 12:51

GoogleCodeExporter commented 9 years ago
I'm interested in putting the work to port Mutagen to Python 3.2. However, I'm 
somewhat skeptical about the feasibility of preserving Python 2.4 compatibility 
in the process. (The simplest route probably involves targeting 2.6 as a 
minimum version.) So I'd be interested in others' opinions about how to deal 
with backwards compatibility:
- How onerous would it be to maintain separate codebases for Python 2.x and 3.x?
- Is 2.4/2.5 support still important?
- Maybe I'm wrong and supporting 2.4 is easier than I think?

Original comment by adrian.sampson on 14 May 2012 at 5:14

GoogleCodeExporter commented 9 years ago
I tried brian's diff... but (aside of obviously being incomplete), it does 
nothing to try to make the test suite ran under python3

I started my effort to port mutagen to python3: it's still far from being 
complete, but at least all the tests in the following TestCases work fine:

Tis_valid_apev2_key TAPEWriter TAPEv2ThenID3v1Writer TAPEv2 TAPEv2ThenID3v1 
TAPEv2WithLyrics2 TAPEBinaryValue TAPETextValue TAPEExtValue TAPEv2File Tistag 
TVComment TVCommentDict Tto_int_be TVCFLACDict TMetadataBlock TStreamInfo 
TSeekTable TCueSheet TPicture TPadding TFLAC TFLACFile TFLACBadBlockSize 
TFLACBadBlockSizeWrite CVE20074619 TEasyMP4 TWavPack

I probably won't be able to continue working on it in the next few days, so if 
someone wants to work on it, please go ahead :)

my code is on a branch of the launchpad mirror of the project:
https://code.launchpad.net/~berdario/mutagen/mutagen-py3

Original comment by berdario on 21 Jun 2012 at 4:30

GoogleCodeExporter commented 9 years ago
Good news:
All the tests now pass under python3!

There's still a lot of cleanup to do, btw I already tested it by making a 
friend's script run with mutagen on python3... but it only uses the EasyMP3 
module

so, I had to change lots of tests: they now make use of bytes literals and 
expect bytes objects back, but I actually never used that user-facing part of 
the library 

I think that it would be quite user-unfriendly to have such changes to the API 
(but I think that Easy* should work more or less as before)

so: please test any programs that you have against my branch, and let me know 
if something breaks horribly :D

here's again the link to the branch:
https://code.launchpad.net/~berdario/mutagen/mutagen-py3

Original comment by berdario on 25 Jul 2012 at 3:56

GoogleCodeExporter commented 9 years ago
Awesome! I'm excited to give this fork a try in my code.

I took a look at your repository on LaunchPad and, at a cursory glance, it 
looks like the API still uses mostly Unicode strings (which is what I would 
have expected). Can you explain what you mean by saying that the tests use 
bytes objects now? Are bytes only in certain places, like MPEG-4 atom names?

Original comment by adrian.sampson on 25 Jul 2012 at 5:52

GoogleCodeExporter commented 9 years ago
Yes, only in certain places, and indeed one of the test suites that changed 
more is MPEG4's

the tests make use of lots of low level methods, like _readData or Atom.render()

I think that it's fine there if now it requires some arguments to be bytes

another thing I was wary of, is the MP4Tags class: in a test I had to use bytes 
as keys (in fact the keys are the atom names)

Original comment by berdario on 25 Jul 2012 at 12:31

GoogleCodeExporter commented 9 years ago
Mutagen has a good coverage, so this seems to be a good start.

Do you have any plans on how to maintain it? I'd suggest to move mutagen to 
git/hg and make a py3k branch. To make merging/diffing/bug management easier.

Original comment by reiter.christoph@gmail.com on 30 Jul 2012 at 11:06

GoogleCodeExporter commented 9 years ago
Uhm, I was waiting for feedback from library users and joe wreschnig and I 
completely failed to notice that since july you've been fixing bugs and adding 
new commits to the trunk.

The reason for my silence was also that I don't really have any investment in 
mutagen (the friend I mentioned before was the only really practical reason for 
the conversion effort), and thus I neglected it.

In the meanwhile btw I was starting to clean up the code by following pyflakes 
and pylint suggestions... given that mutagen is a quite stable codebase I 
wouldn't mind to help to mantain it 

but since you're the main developer right now, I have to ask: would such 
cleanup changes be frowned upon?

To solve the problem of lack of feedback on this port, I was thinking of 
uploading it as a separate package on pypi, thus making it easier for people to 
test it
(a better solution would be to have a single package and to work on a single 
source, for that purpose I was looking into 3to2)

about the VCS: do you have any problem with bzr?

Original comment by berdario on 21 Oct 2012 at 10:47

GoogleCodeExporter commented 9 years ago
The reason for my silence was also that I don't really have any
> investment in mutagen (the friend I mentioned before was the only
> really practical reason for the conversion effort), and thus I
> neglected it.

Me neither, moving Quod Libet to python3 is out of question until we
port to PyGObject. ..but mutagen has to make the first step here.

> In the meanwhile btw I was starting to clean up the code by following
> pyflakes and pylint suggestions... given that mutagen is a quite stable
> codebase I wouldn't mind to help to mantain it 
> 
> but since you're the main developer right now, I have to ask: would
> such cleanup changes be frowned upon?

No, but I would like to see a new release first. btw. you can remove
the m4a module. It's deprecated in mutagen, so there is no need to keep
it around.

> To solve the problem of lack of feedback on this port, I was thinking
> of uploading it as a separate package on pypi, thus making it easier
> for people to test it (a better solution would be to have a single
> package and to work on a single source, for that purpose I was looking
> into 3to2)

Posting it to the mailing list might also be a good idea.
In any case, mark it alpha ("may eat your files"). I can't promise you
anything, but I'll try to look over it sometime.

> about the VCS: do you have any problem with bzr?

No, but the question is why use something different for code hosting
than the main project?

Original comment by reiter.christoph@gmail.com on 22 Oct 2012 at 2:43

GoogleCodeExporter commented 9 years ago
about the VCS: I'd have agreed if mutagen was developed with hg or git... 
cloning on google code wouldn't be a problem

but with svn, you cannot do that with a single click... and since I would've 
used a dvcs to work on it locally btw, I chose to use the already existing 
launchpad mirror

(besides: since I don't have commit rights, having a clone here made with 
hg-svn or on some other place doesn't really make it much easier to merge back 
the changes, until mutagen switches away from svn)

about switching away from svn: it's probably not anyone's priority, but I think 
that given how little effort it takes we could just do it (after agreeing on 
which one to migrate to, obviously)

about the rest: I'll try to complete the changes (w/ merging your fixes in my 
branch, and possibly getting 3to2 working) in the next week

Original comment by berdario on 22 Oct 2012 at 4:11

GoogleCodeExporter commented 9 years ago
That's why I wrote "I'd suggest to move mutagen to git/hg". But that's not my 
decision to make.

Original comment by reiter.christoph@gmail.com on 22 Oct 2012 at 5:08

GoogleCodeExporter commented 9 years ago
Just curious, would it be worth trying to support Python 2 and 3 with a single 
codebase, using something like the six library (the way Django is doing)? It 
might end up easier to do that than to keep two separate codebases in sync.

Original comment by mjjohnso...@gmail.com on 4 Nov 2012 at 2:49

GoogleCodeExporter commented 9 years ago

Original comment by reiter.christoph@gmail.com on 22 Apr 2013 at 2:04

GoogleCodeExporter commented 9 years ago
"next week" came and went away... I'm sorry but as I said, I have no real 
investment in this project

By the way, I tried to bring back to Python2 my Python3 branch with 3to2 (the 
idea being that, once "the bytes and the unicodes" have been splitted, it 
should be easier to convert it to Py2 than doing it the other way around to 
Py3), and unfortunately I realized that I should have attempted the porting in 
a different way:

I think it would've been better to start by converting every python2 native 
string literal to bytes literal, and go on from there by "upgrading" to unicode 
when truly needed...

Obviously, I never thought to have two separate codebases and try to keep them 
in sync... the idea was to use some tooling (i.e. 3to2) to automatically 
convert the code at release time (or possibly, at install time with pip)

On the bright side: now Python3.3 is the de-facto standard Python3... Python3.2 
isn't even available in the main repositories of the latest Ubuntu.
Instead of having a mostly-agnostic codebase that can then be automatically 
ported, it's surely better to have a codebase that is completely agnostic from 
the start... and Py3.3 enables us to have that without using wrappers like the 
six module's

If someone else is interested, and hasn't already read it, I suggest to have a 
look at Ronacher's post:
http://lucumr.pocoo.org/2013/5/21/porting-to-python-3-redux/

Now that the trunk is on mercurial, I'll try to merge as soon as I have 
something that passes the tests on both Py2 and Py3... the more I wait, the 
harder it'll be to merge with the changes that have been done in trunk, and the 
greater the risk of wasting the work that I've done until now... obviously I 
don't want that :)

OTOH: If someone's willing to pick up from where I am right now (or want to 
redo it from scratch from the current trunk)... just let me know

Original comment by berdario on 30 Jun 2013 at 11:17

GoogleCodeExporter commented 9 years ago
I'm also working on translating mutagen to Python 3. I'm not going to support 
Python 2.x, because mutagen itself already does that just fine, and I decided 
it's too much work to try to get 2/3 compatability. I plan on releasing new 
versions mainly in line with new versions of mutagen, and will port the 
differences between the versions each time.

Currently, ID3 and EasyID3 are mostly done, I'm currently adding tests and 
fixing any bugs I come across as I add them. Will then add in Ogg Vorbis and 
FLAC, followed by the other formats. Tested it out reading 9000 of my MP3s and 
it seemed to work just fine.

The GitHub page is here: https://github.com/LordSputnik/mutagen

The master branch contains the Python 3 code, the original branch obviously has 
the original mutagen 1.21 code. Because I'm not trying to be backwards 
compatible, I'll probably introduce small changes and tweaks (eg. support for 
saving to ID3v2.3), but nothing too major. And I'm also changing the style to 
follow PEP 8 as I go.

Original comment by Ben.S...@gmail.com on 24 Jul 2013 at 10:49

GoogleCodeExporter commented 9 years ago
I managed to port the code back to Python2!

https://code.launchpad.net/~berdario/mutagen/mutagen-py3

Now it works with the same codebase on both python2 (2.7) and python3 (3.3)
As I gave notice before: after fixing some other small issues, now I'll put it 
into a mercurial branch, and try to see if a merge works without too many 
conflicts

@BenSput: uhm, a rewrite is a risky endeavor... but you started by reusing the 
old code, so I guess it's fine...

still: you're not planning to try to merge it back? it's in git, and you 
labeled it as a different library: "Project to create a Python 2.7/3.3 library 
functionally equivalent to mutagen."

Original comment by berdario on 2 Aug 2013 at 9:12