Browse Source

[python] some love for tuple

 - move python.lib.Tuple -> python.Tuple
 - rename Tup* classes to Tuple* for consistency
 - fix generation of single-element tuples
 - add Tuple1
 - fixed construction of Tuple* using new operator
 - reserve tuple soft-keyword so we don't need to import "tuple" from builtins
Dan Korostelev 10 years ago
parent
commit
f0d16420ed

+ 6 - 2
genpy.ml

@@ -79,7 +79,7 @@ module KeywordHandler = struct
 		let h = Hashtbl.create 0 in
 		List.iter (fun s -> Hashtbl.add h s ()) [
 			"len"; "int"; "float"; "list"; "bool"; "str"; "isinstance"; "print"; "min"; "max";
-			"hasattr"; "getattr"; "setattr"; "callable"; "type"; "ord"; "chr"; "iter"; "map"; "filter"
+			"hasattr"; "getattr"; "setattr"; "callable"; "type"; "ord"; "chr"; "iter"; "map"; "filter"; "tuple";
 		];
 		h
 
@@ -1549,7 +1549,11 @@ module Printer = struct
 			| "python_Syntax.field",[e1;{eexpr = TConst(TString id)}] ->
 				Printf.sprintf "%s.%s" (print_expr pctx e1) id
 			| "python_Syntax._tuple", [{eexpr = TArrayDecl el}] ->
-				Printf.sprintf "(%s)" (print_exprs pctx ", " el)
+				(match el with
+				| [e] ->
+					Printf.sprintf "(%s,)" (print_expr pctx e)
+				| _ ->
+					Printf.sprintf "(%s)" (print_exprs pctx ", " el))
 			| "python_Syntax._arrayAccess", e1 :: {eexpr = TArrayDecl el} :: etrail ->
 				let trailing_colon = match etrail with
 					| [{eexpr = TConst(TBool(true))}] -> true

+ 2 - 2
std/python/NativeStringTools.hx

@@ -22,7 +22,7 @@
 package python;
 
 import python.lib.Bytes;
-import python.lib.Tuple;
+import python.Tuple;
 
 class NativeStringTools {
 
@@ -44,7 +44,7 @@ class NativeStringTools {
 		return python.Syntax.field(s, "strip")(chars);
 	}
 
-	public static inline function rpartition (s:String, sep:String):Tup3<String, String, String>
+	public static inline function rpartition (s:String, sep:String):Tuple3<String, String, String>
 	{
 		return python.Syntax.field(s, "rpartition")(sep);
 	}

+ 96 - 0
std/python/Tuple.hx

@@ -0,0 +1,96 @@
+/*
+ * Copyright (C)2005-2015 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package python;
+
+import python.internal.UBuiltins;
+import python.Syntax;
+
+@:native("tuple")
+extern class Tuple<X> implements ArrayAccess<X> {
+	@:overload(function():Void {})
+	function new(a:Array<X>):Void;
+
+	var length(get,never):Int;
+
+	inline function get_length():Int {
+		return UBuiltins.len(this);
+	}
+
+	inline function toArray():Array<X> {
+		return UBuiltins.list(this);
+	}
+}
+
+@:native("tuple")
+extern class Tuple1<A> extends Tuple<Dynamic> {
+	static inline function create<A>(a:A):Tuple1<A> return Syntax.tuple(a);
+	var _1(get, null):A;
+	inline function get__1():A return this[0];
+}
+
+@:native("tuple")
+extern class Tuple2<A,B> extends Tuple<Dynamic> {
+	static inline function create <A,B>(a:A, b:B):Tuple2<A,B> return Syntax.tuple(a,b);
+	var _1(get, null):A;
+	inline function get__1():A return this[0];
+	var _2(get, null):B;
+	inline function get__2():B return this[1];
+}
+
+@:native("tuple")
+extern class Tuple3<A,B,C> extends Tuple<Dynamic> {
+	static inline function create <A,B,C>(a:A, b:B,c:C):Tuple3<A,B,C> return Syntax.tuple(a,b,c);
+	var _1(get, null):A;
+	inline function get__1():A return this[0];
+	var _2(get, null):B;
+	inline function get__2():B return this[1];
+	var _3(get, null):C;
+	inline function get__3():C return this[2];
+}
+
+@:native("tuple")
+extern class Tuple4<A,B,C,D> extends Tuple<Dynamic> {
+	static inline function create <A,B,C,D>(a:A, b:B,c:C,d:D):Tuple4<A,B,C,D> return Syntax.tuple(a,b,c,d);
+	var _1(get, null):A;
+	inline function get__1():A return this[0];
+	var _2(get, null):B;
+	inline function get__2():B return this[1];
+	var _3(get, null):C;
+	inline function get__3():C return this[2];
+	var _4(get, null):D;
+	inline function get__4():D return this[3];
+}
+
+@:native("tuple")
+extern class Tuple5<A,B,C,D,E> extends Tuple<Dynamic> {
+	static inline function create <A,B,C,D,E>(a:A, b:B,c:C,d:D,e:E):Tuple5<A,B,C,D,E> return Syntax.tuple(a,b,c,d,e);
+	var _1(get, null):A;
+	inline function get__1():A return this[0];
+	var _2(get, null):B;
+	inline function get__2():B return this[1];
+	var _3(get, null):C;
+	inline function get__3():C return this[2];
+	var _4(get, null):D;
+	inline function get__4():D return this[3];
+	var _5(get, null):E;
+	inline function get__5():E return this[4];
+}

+ 2 - 2
std/python/_std/sys/net/Socket.hx

@@ -25,7 +25,7 @@ import haxe.io.Error;
 import haxe.io.Bytes;
 import haxe.io.BytesData;
 import python.lib.Exceptions;
-import python.lib.Tuple;
+import python.Tuple;
 import python.lib.net.Socket in PSocket;
 import python.lib.net.Socket.Select in Select;
 import python.lib.net.Address in PAddress;
@@ -197,7 +197,7 @@ private class SocketOutput extends haxe.io.Output {
         Accept a new connected client. This will return a connected socket on which you can read/write some data.
     **/
     public function accept() : Socket {
-        var tp2:Tup2<PSocket,PAddress> = __s.accept();
+        var tp2:Tuple2<PSocket,PAddress> = __s.accept();
         var s = new Socket();
         s.__s = tp2._1;
         s.input = new SocketInput(s.__s);

+ 2 - 2
std/python/lib/Dict.hx

@@ -22,7 +22,7 @@
 package python.lib;
 
 import python.internal.UBuiltins;
-import python.lib.Tuple;
+import python.Tuple;
 import python.NativeIterator;
 import python.Syntax;
 
@@ -66,7 +66,7 @@ extern class Dict <K, V>
 
 	public function keys ():DictView<K>;
 	public function values ():DictView<V>;
-	public function items ():DictView<Tup2<K,V>>;
+	public function items ():DictView<Tuple2<K,V>>;
 
 
 	public inline function set (key:K, val:V):Void {

+ 2 - 2
std/python/lib/Inspect.hx

@@ -21,11 +21,11 @@
  */
 package python.lib;
 
-import python.lib.Tuple.Tup2;
+import python.Tuple.Tuple2;
 
 @:pythonImport("inspect")
 extern class Inspect {
-	static function getmembers(object:Dynamic, ?predicate:Dynamic->Bool):Array<Tup2<String,Dynamic>>;
+	static function getmembers(object:Dynamic, ?predicate:Dynamic->Bool):Array<Tuple2<String,Dynamic>>;
 	static function ismethod(object:Dynamic):Bool;
 	static function isclass(object:Dynamic):Bool;
 	static function isfunction(object:Dynamic):Bool;

+ 2 - 2
std/python/lib/Json.hx

@@ -23,7 +23,7 @@ package python.lib;
 
 import python.KwArgs;
 import python.lib.Dict;
-import python.lib.Tuple.Tup2;
+import python.Tuple.Tuple2;
 
 @:pythonImport("json")
 extern class Json {
@@ -38,6 +38,6 @@ extern class Json {
 	public static function dumps (x:Dynamic, skipkeys:Bool=false, ensure_ascii:Bool=true, check_circular:Bool=true,
 		allow_nan:Bool=true,
 		cls:Null<Dynamic> = null, indent:Null<String> = null,
-		separators:Null<Tup2<String,String>>, /*default*/def:Null<Dynamic->String> = null, sort_keys:Bool=false, kw:KwArgs<Dynamic> = null):String;
+		separators:Null<Tuple2<String,String>>, /*default*/def:Null<Dynamic->String> = null, sort_keys:Bool=false, kw:KwArgs<Dynamic> = null):String;
 
 }

+ 2 - 2
std/python/lib/Os.hx

@@ -23,7 +23,7 @@ package python.lib;
 
 
 import python.lib.Exceptions.OSError;
-import python.lib.Tuple;
+import python.Tuple;
 
 extern class Stat {
 	public var st_mode:Int;
@@ -81,7 +81,7 @@ extern class Os {
 
 	public static function listdir (path:String = "."):Array<String>;
 
-	public static function walk (top:String, topdown:Bool = true, onerror:OSError->Void = null, followlinks:Bool = false):Tup3<String, Array<String>, Array<String>>;
+	public static function walk (top:String, topdown:Bool = true, onerror:OSError->Void = null, followlinks:Bool = false):Tuple3<String, Array<String>, Array<String>>;
 
 	public static var sep(default, null) : String;
 	public static var pathsep(default, null):String;

+ 2 - 2
std/python/lib/Re.hx

@@ -21,7 +21,7 @@
  */
 package python.lib;
 
-import python.lib.Tuple;
+import python.Tuple;
 
 
 private abstract Choice <A,B>(Dynamic) {
@@ -62,7 +62,7 @@ extern class MatchObject
 	@:overload(function (x:String):Int {})
 	public function end (?i:Int = 0):Int;
 
-	public function span (?i:Int):Tup2<Int, Int>;
+	public function span (?i:Int):Tuple2<Int, Int>;
 
 
 	public inline function groupById(s:String):String {

+ 2 - 2
std/python/lib/Sys.hx

@@ -25,7 +25,7 @@ import python.lib.Exceptions.BaseException;
 import python.lib.io.FileIO;
 import python.lib.io.RawIOBase;
 import python.lib.io.TextIOBase;
-import python.lib.Tuple.Tup3;
+import python.Tuple.Tuple3;
 
 
 extern class TB {}
@@ -51,6 +51,6 @@ extern class Sys {
 
 	public static var maxsize:Int;
 
-	public static function exc_info<T:BaseException>():Tup3<Class<T>, T, TB>;
+	public static function exc_info<T:BaseException>():Tuple3<Class<T>, T, TB>;
 
 }

+ 1 - 1
std/python/lib/ThreadLowLevel.hx

@@ -21,7 +21,7 @@
  */
 package python.lib;
 
-import python.lib.Tuple;
+import python.Tuple;
 
 private typedef TODO = Dynamic;
 

+ 2 - 2
std/python/lib/Traceback.hx

@@ -23,7 +23,7 @@ package python.lib;
 
 import python.lib.Sys;
 import python.lib.Sys.Frame;
-import python.lib.Tuple;
+import python.Tuple;
 
 @:pythonImport("traceback")
 extern class Traceback {
@@ -33,4 +33,4 @@ extern class Traceback {
 
 }
 
-private typedef StackItem = Tup4<String, Int, String, String>;
+private typedef StackItem = Tuple4<String, Int, String, String>;

+ 0 - 92
std/python/lib/Tuple.hx

@@ -1,92 +0,0 @@
-/*
- * Copyright (C)2005-2012 Haxe Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-package python.lib;
-
-import python.internal.UBuiltins;
-import python.Syntax;
-
-@:pythonImport("builtins", "tuple")
-extern class Tuple<X> implements ArrayAccess<X> {
-
-	@:overload(function ():Void {})
-	public function new (a:Array<X>):Void;
-
-	public var length(get_length,never):Int;
-
-	inline function get_length():Int {
-		return UBuiltins.len(this);
-	}
-
-	public inline function toArray ():Array<X>
-	{
-		return UBuiltins.list(this);
-	}
-
-}
-
-extern class Tup2 <A,B> extends Tuple<Dynamic>
-{
-	public static inline function create <A,B>(a:A, b:B):Tup2<A,B> return Syntax.tuple(a,b);
-	public var _1(get, null):A;
-	public inline function get__1():A return this[0];
-	public var _2(get, null):B;
-	public inline function get__2():B return this[1];
-}
-
-extern class Tup3 <A,B,C> extends Tuple<Dynamic>
-{
-	public static inline function create <A,B,C>(a:A, b:B,c:C):Tup3<A,B,C> return Syntax.tuple(a,b,c);
-	public var _1(get, null):A;
-	public inline function get__1():A return this[0];
-	public var _2(get, null):B;
-	public inline function get__2():B return this[1];
-	public var _3(get, null):C;
-	public inline function get__3():C return this[2];
-}
-
-extern class Tup4 <A,B,C,D> extends Tuple<Dynamic>
-{
-	public static inline function create <A,B,C,D>(a:A, b:B,c:C,d:D):Tup4<A,B,C,D> return Syntax.tuple(a,b,c,d);
-	public var _1(get, null):A;
-	public inline function get__1():A return this[0];
-	public var _2(get, null):B;
-	public inline function get__2():B return this[1];
-	public var _3(get, null):C;
-	public inline function get__3():C return this[2];
-	public var _4(get, null):D;
-	public inline function get__4():D return this[3];
-}
-
-extern class Tup5 <A,B,C,D,E> extends Tuple<Dynamic>
-{
-	public static inline function create <A,B,C,D,E>(a:A, b:B,c:C,d:D,e:E):Tup5<A,B,C,D,E> return Syntax.tuple(a,b,c,d,e);
-	public var _1(get, null):A;
-	public inline function get__1():A return this[0];
-	public var _2(get, null):B;
-	public inline function get__2():B return this[1];
-	public var _3(get, null):C;
-	public inline function get__3():C return this[2];
-	public var _4(get, null):D;
-	public inline function get__4():D return this[3];
-	public var _5(get, null):E;
-	public inline function get__5():E return this[4];
-}

+ 5 - 5
std/python/lib/codecs/Codec.hx

@@ -22,15 +22,15 @@
 package python.lib.codecs;
 
 import python.lib.Bytes;
-import python.lib.Tuple.Tup2;
+import python.Tuple.Tuple2;
 
 @:pythonImport("codecs", "Codec")
 extern class Codec implements ICodec {
-	public function encode(input:Dynamic, ?errors:String = "strict"):Tup2<String, Int>;
-	public function decode(input:Dynamic, ?errors:String = "strict"):Tup2<Bytes, Int>;
+	public function encode(input:Dynamic, ?errors:String = "strict"):Tuple2<String, Int>;
+	public function decode(input:Dynamic, ?errors:String = "strict"):Tuple2<Bytes, Int>;
 }
 
 @:remove extern interface ICodec {
-	public function encode(input:Dynamic, ?errors:String = "strict"):Tup2<String, Int>;
-	public function decode(input:Dynamic, ?errors:String = "strict"):Tup2<Bytes, Int>;
+	public function encode(input:Dynamic, ?errors:String = "strict"):Tuple2<String, Int>;
+	public function decode(input:Dynamic, ?errors:String = "strict"):Tuple2<Bytes, Int>;
 }

+ 1 - 1
std/python/lib/net/Address.hx

@@ -21,4 +21,4 @@
  */
 package python.lib.net;
 
-typedef Address = python.lib.Tuple.Tup2<String,Int>;
+typedef Address = python.Tuple.Tuple2<String,Int>;

+ 3 - 3
std/python/lib/net/Socket.hx

@@ -22,7 +22,7 @@
 package python.lib.net;
 
 import haxe.io.BytesData;
-import python.lib.Tuple;
+import python.Tuple;
 
 /**
     A TCP socket class : allow you to both connect to a given server and exchange messages or start your own server and wait for connections.
@@ -36,7 +36,7 @@ typedef Selectable = {
 @:pythonImport("select")
 extern class Select {
 
-    static function select<T>(reads:Array<T>,writes:Array<T>,xs:Array<T>,timeout:Float):Tup3<Array<T>,Array<T>,Array<T>>;
+    static function select<T>(reads:Array<T>,writes:Array<T>,xs:Array<T>,timeout:Float):Tuple3<Array<T>,Array<T>,Array<T>>;
 
 }
 
@@ -345,7 +345,7 @@ extern class Socket {
     /**
         Accept a new connected client. This will return a connected socket on which you can read/write some data.
     **/
-    function accept() : Tup2<Socket,Address>;
+    function accept() : Tuple2<Socket,Address>;
 
     /**
         Return the informations about the other side of a connected socket.

+ 4 - 4
std/python/lib/os/Path.hx

@@ -21,7 +21,7 @@
  */
 package python.lib.os;
 
-import python.lib.Tuple;
+import python.Tuple;
 
 @:pythonImport("os", "path")
 extern class Path {
@@ -73,11 +73,11 @@ extern class Path {
 
 	public static function samefile (path1:String, path2:String):String;
 
-	public static function split (path:String):Tup2<String, String>;
+	public static function split (path:String):Tuple2<String, String>;
 
-	public static function splitdrive (path:String):Tup2<String, String>;
+	public static function splitdrive (path:String):Tuple2<String, String>;
 
-	public static function splitext (path:String):Tup2<String, String>;
+	public static function splitext (path:String):Tuple2<String, String>;
 
 	public static function supports_unicode_filenames ():Bool;
 

+ 2 - 2
std/python/lib/subprocess/Popen.hx

@@ -25,7 +25,7 @@ import python.lib.io.BufferedReader;
 import python.lib.io.FileIO;
 import python.lib.io.TextIOBase;
 import python.lib.Subprocess.StartupInfo;
-import python.lib.Tuple;
+import python.Tuple;
 
 typedef PopenOptions = {
 	?bufsize : Int,
@@ -92,6 +92,6 @@ extern class Popen {
 	public var returncode : Int;
 	public var pid:Int;
 
-	public function communicate (input:Bytes = null, timeout:Null<Int> = null):Tup2<Bytes, Bytes>;
+	public function communicate (input:Bytes = null, timeout:Null<Int> = null):Tuple2<Bytes, Bytes>;
 
 }

+ 2 - 2
std/python/lib/xml/etree/ElementTree.hx

@@ -21,7 +21,7 @@
  */
 package python.lib.xml.etree;
 
-import python.lib.Tuple.Tup2;
+import python.Tuple.Tuple2;
 
 import python.NativeIterable;
 import python.NativeIterator;
@@ -44,7 +44,7 @@ extern class Element {
 	public function copy ():Element;
 
 	public function keys ():Array<String>;
-	public function items ():Array<Tup2<String, String>>;
+	public function items ():Array<Tuple2<String, String>>;
 
 	public function iter (tag:String):NativeIterable<Element>;
 	public function iterfind (tag:String, namespaces:Dict<String,String> = null):NativeIterator<Element>;

+ 9 - 5
tests/unit/src/unit/TestPython.hx

@@ -32,7 +32,7 @@ import python.lib.ThreadLowLevel;
 import python.lib.Time;
 import python.lib.Traceback;
 import python.lib.Tty;
-import python.lib.Tuple;
+import python.Tuple;
 
 import python.lib.datetime.Datetime;
 import python.lib.datetime.Timedelta;
@@ -371,25 +371,29 @@ class TestPython extends Test {
 	}
 
 	function testTupleCreation() {
-		var t = Tup2.create(1, 2);
+		var t = Tuple1.create(1);
+		eq(t._1, 1);
+		eq(t.length, 1);
+
+		var t = Tuple2.create(1, 2);
 		eq(t._1, 1);
 		eq(t._2, 2);
 		eq(t.length, 2);
 
-		var t = Tup3.create(1, 2, 3);
+		var t = Tuple3.create(1, 2, 3);
 		eq(t._1, 1);
 		eq(t._2, 2);
 		eq(t._3, 3);
 		eq(t.length, 3);
 
-		var t = Tup4.create(1, 2, 3, 4);
+		var t = Tuple4.create(1, 2, 3, 4);
 		eq(t._1, 1);
 		eq(t._2, 2);
 		eq(t._3, 3);
 		eq(t._4, 4);
 		eq(t.length, 4);
 
-		var t = Tup5.create(1, 2, 3, 4, 5);
+		var t = Tuple5.create(1, 2, 3, 4, 5);
 		eq(t._1, 1);
 		eq(t._2, 2);
 		eq(t._3, 3);