[Jython-checkins] jython: First cut at complex __format__.

frank.wierzbicki jython-checkins at python.org
Wed Apr 4 07:25:49 CEST 2012


http://hg.python.org/jython/rev/8dc0dabd4e4b
changeset:   6528:8dc0dabd4e4b
user:        Frank Wierzbicki <fwierzbicki at gmail.com>
date:        Tue Apr 03 22:25:35 2012 -0700
summary:
  First cut at complex __format__.

files:
  src/org/python/core/PyComplex.java           |  48 ++++++++++
  src/org/python/core/stringlib/Formatter.java |  12 ++
  2 files changed, 60 insertions(+), 0 deletions(-)


diff --git a/src/org/python/core/PyComplex.java b/src/org/python/core/PyComplex.java
--- a/src/org/python/core/PyComplex.java
+++ b/src/org/python/core/PyComplex.java
@@ -4,6 +4,10 @@
  */
 package org.python.core;
 
+import org.python.core.stringlib.Formatter;
+import org.python.core.stringlib.InternalFormatSpec;
+import org.python.core.stringlib.InternalFormatSpecParser;
+
 import org.python.expose.ExposedGet;
 import org.python.expose.ExposedMethod;
 import org.python.expose.ExposedNew;
@@ -780,6 +784,50 @@
     }
 
     @Override
+    public PyObject __format__(PyObject formatSpec) {
+        return complex___format__(formatSpec);
+    }
+
+    @ExposedMethod(doc = BuiltinDocs.complex___format___doc)
+    final PyObject complex___format__(PyObject formatSpec) {
+        return formatImpl(real, imag, formatSpec);
+    }
+
+    static PyObject formatImpl(double r, double i, PyObject formatSpec) {
+        if (!(formatSpec instanceof PyString)) {
+            throw Py.TypeError("__format__ requires str or unicode");
+        }
+
+        PyString formatSpecStr = (PyString) formatSpec;
+        String result;
+        try {
+            String specString = formatSpecStr.getString();
+            InternalFormatSpec spec = new InternalFormatSpecParser(specString).parse();
+            switch (spec.type) {
+                case '\0': /* No format code: like 'g', but with at least one decimal. */
+                case 'e':
+                case 'E':
+                case 'f':
+                case 'F':
+                case 'g':
+                case 'G':
+                case 'n':
+                case '%':
+                    result = Formatter.formatComplex(r, i, spec);
+                    break;
+                default:
+                    /* unknown */
+                    throw Py.ValueError(String.format("Unknown format code '%c' for object of type 'complex'",
+                                            spec.type));
+            }
+        } catch (IllegalArgumentException e) {
+            throw Py.ValueError(e.getMessage());
+        }
+        return formatSpecStr.createInstance(result);
+    }
+
+
+    @Override
     public boolean isNumberType() {
         return true;
     }
diff --git a/src/org/python/core/stringlib/Formatter.java b/src/org/python/core/stringlib/Formatter.java
--- a/src/org/python/core/stringlib/Formatter.java
+++ b/src/org/python/core/stringlib/Formatter.java
@@ -8,10 +8,22 @@
 
 
 public class Formatter {
+
     public static String formatFloat(double value, InternalFormatSpec spec) {
         InternalFormatter f = new InternalFormatter(spec);
         return f.format(value);
     }
+
+    public static String formatComplex(double real, double imag, InternalFormatSpec spec) {
+        InternalFormatter f = new InternalFormatter(spec);
+        String r = f.format(real);
+        String i = f.format(imag);
+        if (i.charAt(0) == '-') {
+            return r + i + "j";
+        } else {
+            return r + "+" + i + "j";
+        }
+    }
 }
 
 //Adapted from PyString's StringFormatter class.

-- 
Repository URL: http://hg.python.org/jython


More information about the Jython-checkins mailing list