mikedewar / d3py

a plottling library for python, based on D3
1.42k stars 202 forks source link

support for python 3 #65

Open kern3020 opened 11 years ago

kern3020 commented 11 years ago

At the moment, d3py needs some modifications to work on Python 3. I think all the supporting modules are available on py 3. How about d3py?

andrewcstewart commented 11 years ago

Is this just because of the change in SimpleHTTPServer in py3?

kern3020 commented 11 years ago

No. See output of 2to3 utility below. Some common things that need to be updated are:

Those sort of things.

Regards, John

    (django1.5-py2)jkern@ubuntu:~/workspace/python/d3py/d3py$ 2to3 *.py
    RefactoringTool: Skipping implicit fixer: buffer
    RefactoringTool: Skipping implicit fixer: idioms
    RefactoringTool: Skipping implicit fixer: set_literal
    RefactoringTool: Skipping implicit fixer: ws_comma
    RefactoringTool: Refactored css.py
    --- css.py  (original)
    +++ css.py  (refactored)
    @@ -30,7 +30,7 @@

         def __add__(self, css):
             if isinstance(css, dict):
    -            for selector, declarations in css.iteritems():
    +            for selector, declarations in css.items():
                     try:
                         self.rules[selector].update(declarations)
                     except KeyError:
    @@ -44,9 +44,9 @@

         def __str__(self):
             css = ""
    -        for selector, declarations in self.rules.iteritems():
    +        for selector, declarations in self.rules.items():
                 css += "%s {\n" % selector
    -            for prop, value in declarations.iteritems():
    +            for prop, value in declarations.items():
                     if value is None:
                         value = "none"
                     css += "\t%s: %s;\n" % (prop, value)
    RefactoringTool: Refactored deployable.py
    --- deployable.py   (original)
    +++ deployable.py   (refactored)
    @@ -4,14 +4,12 @@
     import logging
     import os

    -class deployable():
    +class deployable(metaclass=ABCMeta):
         """
         Given a d3py.figure, deployable stores it persistently. Concrete classes
         may simply save the files to the file system or be used to deploy them 
         in the cloud. 
         """
    -    
    -    __metaclass__ = ABCMeta

         def save(self, fig):
             raise NotImplementedError
    @@ -44,7 +42,7 @@
                 os.mkdir(static_dir)
             for k_filename in self.fig.filemap:
                 f = os.path.join(self.dest_dir, k_filename)
    -            with open(f, 'w',0644) as fd_out:
    +            with open(f, 'w',0o644) as fd_out:
                     fd_in = self.fig.filemap[k_filename]["fd"]
                     fd_in.seek(0)
                     # import pdb; pdb.set_trace()
    RefactoringTool: Refactored displayable.py
    --- displayable.py  (original)
    +++ displayable.py  (refactored)
    @@ -6,12 +6,12 @@
     # in support of SimpleServer 
     import threading
     import webbrowser
    -from HTTPHandler import CustomHTTPRequestHandler, ThreadedHTTPServer
    +from .HTTPHandler import CustomHTTPRequestHandler, ThreadedHTTPServer

     # requires IPython 0.11.0 or higher
     import IPython.core.display

    -class displayable():
    +class displayable(metaclass=ABCMeta):
         """
         Given a d3py.figure, displayables present the graph to the user. 
         The first displayable is based on python's SimpleHTTPServer class.
    @@ -19,7 +19,6 @@
         These classes should know nothing of html, css or javascript which
         live in the figure class. 
         """
    -    __metaclass__ = ABCMeta

         def show(self, fig):
             raise NotImplementedError
    @@ -86,14 +85,14 @@
                 Handler.logging = self.fig.logging
                 try:
                     self.httpd = ThreadedHTTPServer(("", self.port), Handler)
    -            except Exception, e:
    -                print "Exception %s"%e
    +            except Exception as e:
    +                print("Exception %s"%e)
                     return False
                 if blocking:
                     logging.info('serving forever on port: %s'%msgparams[1])
                     msg = "You can find your chart at " + url
    -                print msg
    -                print "Ctrl-C to stop serving the chart and quit!"
    +                print(msg)
    +                print("Ctrl-C to stop serving the chart and quit!")
                     self._server_thread = None
                     self.httpd.serve_forever()
                 else:
    @@ -104,7 +103,7 @@
                     self._server_thread.daemon = True
                     self._server_thread.start()
                     msg = "You can find your chart at " + url
    -                print msg
    +                print(msg)

         def __enter__(self):
    @@ -113,7 +112,7 @@

         def __exit__(self, ex_type, ex_value, ex_tb):
             if ex_tb is not None:
    -            print "Cleanup after exception: %s: %s"%(ex_type, ex_value)
    +            print("Cleanup after exception: %s: %s"%(ex_type, ex_value))
             self._cleanup()

         def __del__(self):
    @@ -122,11 +121,11 @@
         def _cleanup(self):
             try:
                 if self.httpd is not None:
    -                print "Shutting down httpd"
    +                print("Shutting down httpd")
                     self.httpd.shutdown()
                     self.httpd.server_close()
    -        except Exception, e:
    -            print "Error in clean-up: %s"%e
    +        except Exception as e:
    +            print("Error in clean-up: %s"%e)

     class IPython(displayable):
         """
    RefactoringTool: Refactored figure.py
    --- figure.py   (original)
    +++ figure.py   (refactored)
    @@ -1,14 +1,14 @@
     import logging

    -from StringIO import StringIO
    +from io import StringIO
     import time
     import json
     import os

     from jinja2 import Template # well-known templating module

    -from css import CSS
    -import javascript as JS
    +from .css import CSS
    +from . import javascript as JS

     class Figure(object):
         """
    @@ -55,7 +55,7 @@
                 "height": height - self.margins["top"] - self.margins["bottom"],
                 "font-family": "'%s'; sans-serif"%self.font
             }
    -        kwargs = dict([(k[0].replace('_','-'), k[1]) for k in kwargs.items()])
    +        kwargs = dict([(k[0].replace('_','-'), k[1]) for k in list(kwargs.items())])
             self.args.update(kwargs)

         def _build(self):
    RefactoringTool: Refactored HTTPHandler.py
    --- HTTPHandler.py  (original)
    +++ HTTPHandler.py  (refactored)
    @@ -1,13 +1,13 @@
    -import SimpleHTTPServer
    -import SocketServer
    -from cStringIO import StringIO
    +import http.server
    +import socketserver
    +from io import StringIO
     import sys

    -class ThreadedHTTPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    +class ThreadedHTTPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
         allow_reuse_address = True

    -class CustomHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    +class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
         def log_message(self, format, *args):
             """
             We get rid of the BaseHTTPRequestHandler logging messages
    @@ -58,7 +58,7 @@
             f.write("<html>\n<title>Directory listing</title>\n")
             f.write("<body>\n<h2>Directory listing</h2>\n")
             f.write("<hr>\n<ul>\n")
    -        for path, meta in self.filemap.iteritems():
    +        for path, meta in self.filemap.items():
                 f.write('<li><a href="%s">%s</a>\n' % (path, path))
             f.write("</ul>\n<hr>\n</body>\n</html>\n")
             length = f.tell()
    RefactoringTool: Refactored __init__.py
    --- __init__.py (original)
    +++ __init__.py (refactored)
    @@ -1,4 +1,4 @@
    -from pandas_figure import *
    -from networkx_figure import *
    -from geoms import *
    -import javascript
    +from .pandas_figure import *
    +from .networkx_figure import *
    +from .geoms import *
    +from . import javascript
    RefactoringTool: Refactored javascript.py
    --- javascript.py   (original)
    +++ javascript.py   (refactored)
    @@ -163,8 +163,8 @@
             elif isinstance(other, Selection):
                 other = [other, ]
             else:
    -            print isinstance(other, Function)
    -            print other.statements
    +            print(isinstance(other, Function))
    +            print(other.statements)
                 logging.debug('failed to convert %s object:\n %s\n\n to statements'%(type(other),other))
                 other = None
             return other
    RefactoringTool: Refactored networkx_figure.py
    --- networkx_figure.py  (original)
    +++ networkx_figure.py  (refactored)
    @@ -2,8 +2,8 @@
     import json
     from networkx.readwrite import json_graph

    -import javascript as JS
    -from figure import Figure
    +from . import javascript as JS
    +from .figure import Figure

     class NetworkXFigure(Figure):
         def __init__(self, graph, name="figure", width=400, height=100, 
    RefactoringTool: Refactored pandas_figure.py
    --- pandas_figure.py    (original)
    +++ pandas_figure.py    (refactored)
    @@ -2,8 +2,8 @@
     import logging
     import json

    -import javascript as JS
    -from figure import Figure
    +from . import javascript as JS
    +from .figure import Figure

     class PandasFigure(Figure):
         def __init__(self, data, name="figure", width=800, height=400, 
    @@ -141,7 +141,7 @@
             ]
             try:
                 s = json.dumps(d, sort_keys=True, indent=4)
    -        except OverflowError, e:
    -            print "Error: Overflow on variable (type %s): %s: %s"%(type(d), d, e)
    +        except OverflowError as e:
    +            print("Error: Overflow on variable (type %s): %s: %s"%(type(d), d, e))
                 raise
             return s
    RefactoringTool: Refactored test.py
    --- test.py (original)
    +++ test.py (refactored)
    @@ -1,8 +1,8 @@
     import unittest
    -import css
    +from . import css
     import pandas
     import d3py
    -import javascript
    +from . import javascript

     class TestCSS(unittest.TestCase):
    RefactoringTool: Files that need to be modified:
    RefactoringTool: css.py
    RefactoringTool: deployable.py
    RefactoringTool: displayable.py
    RefactoringTool: figure.py
    RefactoringTool: HTTPHandler.py
    RefactoringTool: __init__.py
    RefactoringTool: javascript.py
    RefactoringTool: networkx_figure.py
    RefactoringTool: pandas_figure.py
    RefactoringTool: test.py
lxyu commented 11 years ago

I have made a py3 fork & pull request here: https://github.com/mikedewar/d3py/pull/72

You may like to check it.