From 2f45942adc2891f95c422943d5cbdf0ae465a908 Mon Sep 17 00:00:00 2001 From: Hilton Bristow Date: Tue, 24 Dec 2013 15:14:00 +1000 Subject: [PATCH 1/7] converted necessary files for python3 compatibility using 2to3 --- modules/java/generator/rst_parser.py | 96 +++++++++++++------------- modules/matlab/generator/filters.py | 3 +- modules/matlab/generator/parse_tree.py | 21 +++--- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/modules/java/generator/rst_parser.py b/modules/java/generator/rst_parser.py index 63f56dbaaf..d2c3d4019a 100755 --- a/modules/java/generator/rst_parser.py +++ b/modules/java/generator/rst_parser.py @@ -1,6 +1,8 @@ #!/usr/bin/env python +from __future__ import print_function import os, sys, re, string, fnmatch + allmodules = ["core", "flann", "imgproc", "ml", "highgui", "video", "features2d", "calib3d", "objdetect", "legacy", "contrib", "cuda", "androidcamera", "java", "python", "stitching", "ts", "photo", "nonfree", "videostab", "ocl", "softcascade", "superres"] verbose = False show_warnings = True @@ -141,10 +143,10 @@ class RstParser(object): def parse_section_safe(self, module_name, section_name, file_name, lineno, lines): try: self.parse_section(module_name, section_name, file_name, lineno, lines) - except AssertionError, args: + except AssertionError as args: if show_errors: - print >> sys.stderr, "RST parser error E%03d: assertion in \"%s\" at %s:%s" % (ERROR_001_SECTIONFAILURE, section_name, file_name, lineno) - print >> sys.stderr, " Details: %s" % args + print("RST parser error E%03d: assertion in \"%s\" at %s:%s" % (ERROR_001_SECTIONFAILURE, section_name, file_name, lineno), file=sys.stderr) + print(" Details: %s" % args, file=sys.stderr) def parse_section(self, module_name, section_name, file_name, lineno, lines): self.sections_total += 1 @@ -152,7 +154,7 @@ class RstParser(object): #if section_name.find(" ") >= 0 and section_name.find("::operator") < 0: if (section_name.find(" ") >= 0 and not bool(re.match(r"(\w+::)*operator\s*(\w+|>>|<<|\(\)|->|\+\+|--|=|==|\+=|-=)", section_name)) ) or section_name.endswith(":"): if show_errors: - print >> sys.stderr, "RST parser warning W%03d: SKIPPED: \"%s\" File: %s:%s" % (WARNING_002_HDRWHITESPACE, section_name, file_name, lineno) + print("RST parser warning W%03d: SKIPPED: \"%s\" File: %s:%s" % (WARNING_002_HDRWHITESPACE, section_name, file_name, lineno), file=sys.stderr) self.sections_skipped += 1 return @@ -311,7 +313,7 @@ class RstParser(object): if fdecl.balance != 0: if show_critical_errors: - print >> sys.stderr, "RST parser error E%03d: invalid parentheses balance in \"%s\" at %s:%s" % (ERROR_003_PARENTHESES, section_name, file_name, lineno) + print("RST parser error E%03d: invalid parentheses balance in \"%s\" at %s:%s" % (ERROR_003_PARENTHESES, section_name, file_name, lineno), file=sys.stderr) return # save last parameter if needed @@ -328,7 +330,7 @@ class RstParser(object): elif func: if func["name"] in known_text_sections_names: if show_errors: - print >> sys.stderr, "RST parser warning W%03d: SKIPPED: \"%s\" File: %s:%s" % (WARNING_002_HDRWHITESPACE, section_name, file_name, lineno) + print("RST parser warning W%03d: SKIPPED: \"%s\" File: %s:%s" % (WARNING_002_HDRWHITESPACE, section_name, file_name, lineno), file=sys.stderr) self.sections_skipped += 1 elif show_errors: self.print_info(func, True, sys.stderr) @@ -351,7 +353,7 @@ class RstParser(object): if l.find("\t") >= 0: whitespace_warnings += 1 if whitespace_warnings <= max_whitespace_warnings and show_warnings: - print >> sys.stderr, "RST parser warning W%03d: tab symbol instead of space is used at %s:%s" % (WARNING_004_TABS, doc, lineno) + print("RST parser warning W%03d: tab symbol instead of space is used at %s:%s" % (WARNING_004_TABS, doc, lineno), file=sys.stderr) l = l.replace("\t", " ") # handle first line @@ -388,8 +390,8 @@ class RstParser(object): def add_new_fdecl(self, func, decl): if decl.fdecl.endswith(";"): - print >> sys.stderr, "RST parser error E%03d: unexpected semicolon at the end of declaration in \"%s\" at %s:%s" \ - % (ERROR_011_EOLEXPECTED, func["name"], func["file"], func["line"]) + print("RST parser error E%03d: unexpected semicolon at the end of declaration in \"%s\" at %s:%s" \ + % (ERROR_011_EOLEXPECTED, func["name"], func["file"], func["line"]), file=sys.stderr) decls = func.get("decls", []) if (decl.lang == "C++" or decl.lang == "C"): rst_decl = self.cpp_parser.parse_func_decl_no_wrap(decl.fdecl) @@ -405,37 +407,37 @@ class RstParser(object): if show_errors: #check black_list if decl.name not in params_blacklist.get(func["name"], []): - print >> sys.stderr, "RST parser error E%03d: redefinition of parameter \"%s\" in \"%s\" at %s:%s" \ - % (ERROR_005_REDEFENITIONPARAM, decl.name, func["name"], func["file"], func["line"]) + print("RST parser error E%03d: redefinition of parameter \"%s\" in \"%s\" at %s:%s" \ + % (ERROR_005_REDEFENITIONPARAM, decl.name, func["name"], func["file"], func["line"]), file=sys.stderr) else: params[decl.name] = decl.comment func["params"] = params def print_info(self, func, skipped=False, out = sys.stdout): - print >> out + print(file=out) if skipped: - print >> out, "SKIPPED DEFINITION:" - print >> out, "name: %s" % (func.get("name","~empty~")) - print >> out, "file: %s:%s" % (func.get("file","~empty~"), func.get("line","~empty~")) - print >> out, "is class: %s" % func.get("isclass", False) - print >> out, "is struct: %s" % func.get("isstruct", False) - print >> out, "module: %s" % func.get("module","~unknown~") - print >> out, "namespace: %s" % func.get("namespace", "~empty~") - print >> out, "class: %s" % (func.get("class","~empty~")) - print >> out, "method: %s" % (func.get("method","~empty~")) - print >> out, "brief: %s" % (func.get("brief","~empty~")) + print("SKIPPED DEFINITION:", file=out) + print("name: %s" % (func.get("name","~empty~")), file=out) + print("file: %s:%s" % (func.get("file","~empty~"), func.get("line","~empty~")), file=out) + print("is class: %s" % func.get("isclass", False), file=out) + print("is struct: %s" % func.get("isstruct", False), file=out) + print("module: %s" % func.get("module","~unknown~"), file=out) + print("namespace: %s" % func.get("namespace", "~empty~"), file=out) + print("class: %s" % (func.get("class","~empty~")), file=out) + print("method: %s" % (func.get("method","~empty~")), file=out) + print("brief: %s" % (func.get("brief","~empty~")), file=out) if "decls" in func: - print >> out, "declarations:" + print("declarations:", file=out) for d in func["decls"]: - print >> out, " %7s: %s" % (d[0], re.sub(r"[ ]+", " ", d[1])) + print(" %7s: %s" % (d[0], re.sub(r"[ ]+", " ", d[1])), file=out) if "seealso" in func: - print >> out, "seealso: ", func["seealso"] + print("seealso: ", func["seealso"], file=out) if "params" in func: - print >> out, "parameters:" + print("parameters:", file=out) for name, comment in func["params"].items(): - print >> out, "%23s: %s" % (name, comment) - print >> out, "long: %s" % (func.get("long","~empty~")) - print >> out + print("%23s: %s" % (name, comment), file=out) + print("long: %s" % (func.get("long","~empty~")), file=out) + print(file=out) def validate(self, func): if func.get("decls", None) is None: @@ -443,13 +445,13 @@ class RstParser(object): return False if func["name"] in self.definitions: if show_errors: - print >> sys.stderr, "RST parser error E%03d: \"%s\" from: %s:%s is already documented at %s:%s" \ - % (ERROR_006_REDEFENITIONFUNC, func["name"], func["file"], func["line"], self.definitions[func["name"]]["file"], self.definitions[func["name"]]["line"]) + print("RST parser error E%03d: \"%s\" from: %s:%s is already documented at %s:%s" \ + % (ERROR_006_REDEFENITIONFUNC, func["name"], func["file"], func["line"], self.definitions[func["name"]]["file"], self.definitions[func["name"]]["line"]), file=sys.stderr) return False return self.validateParams(func) def validateParams(self, func): - documentedParams = func.get("params", {}).keys() + documentedParams = list(func.get("params", {}).keys()) params = [] for decl in func.get("decls", []): @@ -464,13 +466,13 @@ class RstParser(object): # 1. all params are documented for p in params: if p not in documentedParams and show_warnings: - print >> sys.stderr, "RST parser warning W%03d: parameter \"%s\" of \"%s\" is undocumented. %s:%s" % (WARNING_007_UNDOCUMENTEDPARAM, p, func["name"], func["file"], func["line"]) + print("RST parser warning W%03d: parameter \"%s\" of \"%s\" is undocumented. %s:%s" % (WARNING_007_UNDOCUMENTEDPARAM, p, func["name"], func["file"], func["line"]), file=sys.stderr) # 2. only real params are documented for p in documentedParams: if p not in params and show_warnings: if p not in params_blacklist.get(func["name"], []): - print >> sys.stderr, "RST parser warning W%03d: unexisting parameter \"%s\" of \"%s\" is documented at %s:%s" % (WARNING_008_MISSINGPARAM, p, func["name"], func["file"], func["line"]) + print("RST parser warning W%03d: unexisting parameter \"%s\" of \"%s\" is documented at %s:%s" % (WARNING_008_MISSINGPARAM, p, func["name"], func["file"], func["line"]), file=sys.stderr) return True def normalize(self, func): @@ -541,7 +543,7 @@ class RstParser(object): func["name"] = fname[4:] func["method"] = fname[4:] elif show_warnings: - print >> sys.stderr, "RST parser warning W%03d: \"%s\" - section name is \"%s\" instead of \"%s\" at %s:%s" % (WARNING_009_HDRMISMATCH, fname, func["name"], fname[6:], func["file"], func["line"]) + print("RST parser warning W%03d: \"%s\" - section name is \"%s\" instead of \"%s\" at %s:%s" % (WARNING_009_HDRMISMATCH, fname, func["name"], fname[6:], func["file"], func["line"]), file=sys.stderr) #self.print_info(func) def normalizeText(self, s): @@ -632,11 +634,11 @@ class RstParser(object): return s def printSummary(self): - print "RST Parser Summary:" - print " Total sections: %s" % self.sections_total - print " Skipped sections: %s" % self.sections_skipped - print " Parsed sections: %s" % self.sections_parsed - print " Invalid sections: %s" % (self.sections_total - self.sections_parsed - self.sections_skipped) + print("RST Parser Summary:") + print(" Total sections: %s" % self.sections_total) + print(" Skipped sections: %s" % self.sections_skipped) + print(" Parsed sections: %s" % self.sections_parsed) + print(" Invalid sections: %s" % (self.sections_total - self.sections_parsed - self.sections_skipped)) # statistic by language stat = {} @@ -651,12 +653,12 @@ class RstParser(object): for decl in d.get("decls", []): stat[decl[0]] = stat.get(decl[0], 0) + 1 - print - print " classes documented: %s" % classes - print " structs documented: %s" % structs + print() + print(" classes documented: %s" % classes) + print(" structs documented: %s" % structs) for lang in sorted(stat.items()): - print " %7s functions documented: %s" % lang - print + print(" %7s functions documented: %s" % lang) + print() def mathReplace2(match): m = mathReplace(match) @@ -743,7 +745,7 @@ def mathReplace(match): if __name__ == "__main__": if len(sys.argv) < 2: - print "Usage:\n", os.path.basename(sys.argv[0]), " " + print("Usage:\n", os.path.basename(sys.argv[0]), " ") exit(0) if len(sys.argv) >= 3: @@ -759,7 +761,7 @@ if __name__ == "__main__": module = sys.argv[1] if module != "all" and not os.path.isdir(os.path.join(rst_parser_dir, "../../" + module)): - print "RST parser error E%03d: module \"%s\" could not be found." % (ERROR_010_NOMODULE, module) + print("RST parser error E%03d: module \"%s\" could not be found." % (ERROR_010_NOMODULE, module)) exit(1) parser = RstParser(hdr_parser.CppHeaderParser()) diff --git a/modules/matlab/generator/filters.py b/modules/matlab/generator/filters.py index 6251c8305b..de69ff7e41 100644 --- a/modules/matlab/generator/filters.py +++ b/modules/matlab/generator/filters.py @@ -1,5 +1,4 @@ from textwrap import TextWrapper -from string import split, join import re, os # precompile a URL matching regular expression urlexpr = re.compile(r"((https?):((//)|(\\\\))+[\w\d:#@%/;$()~_?\+-=\\\.&]*)", re.MULTILINE|re.UNICODE) @@ -177,4 +176,4 @@ def comment(text, wrap=80, escape='% ', escape_first='', escape_last=''): escapn = '\n'+escape lines = text.split('\n') wlines = (tw.wrap(line) for line in lines) - return escape_first+escape+join((join(line, escapn) for line in wlines), escapn)+escape_last + return escape_first+escape+escapn.join(escapn.join(line) for line in wlines)+escape_last diff --git a/modules/matlab/generator/parse_tree.py b/modules/matlab/generator/parse_tree.py index daea53c2f2..21c4899ffd 100644 --- a/modules/matlab/generator/parse_tree.py +++ b/modules/matlab/generator/parse_tree.py @@ -1,4 +1,3 @@ -from string import join from textwrap import fill from filters import * @@ -74,7 +73,7 @@ class ParseTree(object): self.namespaces = namespaces if namespaces else [] def __str__(self): - return join((ns.__str__() for ns in self.namespaces), '\n\n\n') + return '\n\n\n'.join(ns.__str__() for ns in self.namespaces) def build(self, namespaces): babel = Translator() @@ -94,7 +93,7 @@ class ParseTree(object): constants.append(obj) else: raise TypeError('Unexpected object type: '+str(type(obj))) - self.namespaces.append(Namespace(name, constants, class_tree.values(), methods)) + self.namespaces.append(Namespace(name, constants, list(class_tree.values()), methods)) def insertIntoClassTree(self, obj, class_tree): cname = obj.name if type(obj) is Class else obj.clss @@ -208,9 +207,9 @@ class Namespace(object): def __str__(self): return 'namespace '+self.name+' {\n\n'+\ - (join((c.__str__() for c in self.constants), '\n')+'\n\n' if self.constants else '')+\ - (join((f.__str__() for f in self.methods), '\n')+'\n\n' if self.methods else '')+\ - (join((o.__str__() for o in self.classes), '\n\n') if self.classes else '')+'\n};' + ('\n'.join(c.__str__() for c in self.constants)+'\n\n' if self.constants else '')+\ + ('\n'.join(f.__str__() for f in self.methods)+'\n\n' if self.methods else '')+\ + ('\n\n'.join(o.__str__() for o in self.classes) if self.classes else '')+'\n};' class Class(object): """ @@ -228,8 +227,8 @@ class Class(object): def __str__(self): return 'class '+self.name+' {\n\t'+\ - (join((c.__str__() for c in self.constants), '\n\t')+'\n\n\t' if self.constants else '')+\ - (join((f.__str__() for f in self.methods), '\n\t') if self.methods else '')+'\n};' + ('\n\t'.join(c.__str__() for c in self.constants)+'\n\n\t' if self.constants else '')+\ + ('\n\t'.join(f.__str__() for f in self.methods) if self.methods else '')+'\n};' class Method(object): """ @@ -260,7 +259,7 @@ class Method(object): def __str__(self): return (self.rtp+' ' if self.rtp else '')+self.name+'('+\ - join((arg.__str__() for arg in self.req+self.opt), ', ')+\ + ', '.join(arg.__str__() for arg in self.req+self.opt)+\ ')'+(' const' if self.const else '')+';' class Argument(object): @@ -343,11 +342,11 @@ def todict(obj, classkey=None): for k in obj.keys(): obj[k] = todict(obj[k], classkey) return obj - elif hasattr(obj, "__iter__"): + elif isinstance(obj, list): return [todict(v, classkey) for v in obj] elif hasattr(obj, "__dict__"): data = dict([(key, todict(value, classkey)) - for key, value in obj.__dict__.iteritems() + for key, value in obj.__dict__.items() if not callable(value) and not key.startswith('_')]) if classkey is not None and hasattr(obj, "__class__"): data[classkey] = obj.__class__.__name__ From 7cad2c6788113f9b3e60846323e9bf3da60cc531 Mon Sep 17 00:00:00 2001 From: Hilton Bristow Date: Tue, 24 Dec 2013 15:15:06 +1000 Subject: [PATCH 2/7] fixed relative imports in Jinja for python3 --- 3rdparty/jinja2/markupsafe/__init__.py | 4 ++-- 3rdparty/jinja2/markupsafe/_native.py | 2 +- 3rdparty/jinja2/utils.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/3rdparty/jinja2/markupsafe/__init__.py b/3rdparty/jinja2/markupsafe/__init__.py index f13d7070df..a602dd5554 100644 --- a/3rdparty/jinja2/markupsafe/__init__.py +++ b/3rdparty/jinja2/markupsafe/__init__.py @@ -9,7 +9,7 @@ :license: BSD, see LICENSE for more details. """ import re -from _compat import text_type, string_types, int_types, \ +from ._compat import text_type, string_types, int_types, \ unichr, PY2 @@ -227,7 +227,7 @@ class _MarkupEscapeHelper(object): try: from _speedups import escape, escape_silent, soft_unicode except ImportError: - from _native import escape, escape_silent, soft_unicode + from ._native import escape, escape_silent, soft_unicode if not PY2: soft_str = soft_unicode diff --git a/3rdparty/jinja2/markupsafe/_native.py b/3rdparty/jinja2/markupsafe/_native.py index 4b4aee3893..81d0777d13 100644 --- a/3rdparty/jinja2/markupsafe/_native.py +++ b/3rdparty/jinja2/markupsafe/_native.py @@ -8,7 +8,7 @@ :copyright: (c) 2010 by Armin Ronacher. :license: BSD, see LICENSE for more details. """ -from _compat import text_type +from ._compat import text_type def escape(s): diff --git a/3rdparty/jinja2/utils.py b/3rdparty/jinja2/utils.py index ddc47da0a0..cbea660b41 100644 --- a/3rdparty/jinja2/utils.py +++ b/3rdparty/jinja2/utils.py @@ -517,4 +517,4 @@ class Joiner(object): # Imported here because that's where it was in the past -from markupsafe import Markup, escape, soft_unicode +from .markupsafe import Markup, escape, soft_unicode From 483061e802c77c3fdc0eb420d4f717b729ff4ff8 Mon Sep 17 00:00:00 2001 From: Hilton Bristow Date: Tue, 24 Dec 2013 16:39:29 +1000 Subject: [PATCH 3/7] explicit string encoding when writing to file in python3 --- modules/matlab/generator/build_info.py | 2 +- modules/matlab/generator/cvmex.py | 2 +- modules/matlab/generator/gen_matlab.py | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/matlab/generator/build_info.py b/modules/matlab/generator/build_info.py index 65619a2a75..1340d9f926 100644 --- a/modules/matlab/generator/build_info.py +++ b/modules/matlab/generator/build_info.py @@ -21,7 +21,7 @@ def substitute(build, output_dir): # populate template populated = template.render(build=build, time=time) with open(os.path.join(output_dir, 'buildInformation.m'), 'wb') as f: - f.write(populated) + f.write(populated.encode('utf-8')) if __name__ == "__main__": """ diff --git a/modules/matlab/generator/cvmex.py b/modules/matlab/generator/cvmex.py index 52c5f649f5..731d30a0e7 100644 --- a/modules/matlab/generator/cvmex.py +++ b/modules/matlab/generator/cvmex.py @@ -22,7 +22,7 @@ def substitute(cv, output_dir): # populate template populated = template.render(cv=cv, time=time) with open(os.path.join(output_dir, 'mex.m'), 'wb') as f: - f.write(populated) + f.write(populated.encode('utf-8')) if __name__ == "__main__": """ diff --git a/modules/matlab/generator/gen_matlab.py b/modules/matlab/generator/gen_matlab.py index 49e575099a..9f0975d97b 100644 --- a/modules/matlab/generator/gen_matlab.py +++ b/modules/matlab/generator/gen_matlab.py @@ -105,27 +105,27 @@ class MatlabWrapperGenerator(object): for method in namespace.methods: populated = tfunction.render(fun=method, time=time, includes=namespace.name) with open(output_source_dir+'/'+method.name+'.cpp', 'wb') as f: - f.write(populated) + f.write(populated.encode('utf-8')) if namespace.name in doc and method.name in doc[namespace.name]: populated = tdoc.render(fun=method, doc=doc[namespace.name][method.name], time=time) with open(output_class_dir+'/'+method.name+'.m', 'wb') as f: - f.write(populated) + f.write(populated.encode('utf-8')) # classes for clss in namespace.classes: # cpp converter populated = tclassc.render(clss=clss, time=time) with open(output_private_dir+'/'+clss.name+'Bridge.cpp', 'wb') as f: - f.write(populated) + f.write(populated.encode('utf-8')) # matlab classdef populated = tclassm.render(clss=clss, time=time) with open(output_class_dir+'/'+clss.name+'.m', 'wb') as f: - f.write(populated) + f.write(populated.encode('utf-8')) # create a global constants lookup table const = dict(constants(todict(parse_tree.namespaces))) populated = tconst.render(constants=const, time=time) with open(output_dir+'/cv.m', 'wb') as f: - f.write(populated) + f.write(populated.encode('utf-8')) if __name__ == "__main__": From 068b1bc3d0793a2fc3e5fc3cd8267d90e15d3b24 Mon Sep 17 00:00:00 2001 From: Hilton Bristow Date: Thu, 27 Mar 2014 11:34:20 +1000 Subject: [PATCH 4/7] More generic todict --- modules/matlab/generator/parse_tree.py | 33 ++++++++++++++++---------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/modules/matlab/generator/parse_tree.py b/modules/matlab/generator/parse_tree.py index 21c4899ffd..bb1d456658 100644 --- a/modules/matlab/generator/parse_tree.py +++ b/modules/matlab/generator/parse_tree.py @@ -1,3 +1,4 @@ +import collections from textwrap import fill from filters import * @@ -333,23 +334,31 @@ def constants(tree): for gen in constants(val): yield gen +def isstring(s): + """ + Check if variable is string representable (regular/unicode/raw) + in a Python 2 and 3 compatible manner + """ + try: + return isinstance(s, basestring) + except NameError: + return isinstance(s, str) + def todict(obj, classkey=None): """ Convert the ParseTree to a dictionary, stripping all objects of their methods and converting class names to strings """ + if isstring(obj): + return obj if isinstance(obj, dict): - for k in obj.keys(): - obj[k] = todict(obj[k], classkey) + obj.update((key, todict(val, classkey)) for key, val in obj.items()) return obj - elif isinstance(obj, list): - return [todict(v, classkey) for v in obj] - elif hasattr(obj, "__dict__"): - data = dict([(key, todict(value, classkey)) - for key, value in obj.__dict__.items() - if not callable(value) and not key.startswith('_')]) - if classkey is not None and hasattr(obj, "__class__"): + if isinstance(obj, collections.Iterable): + return [todict(val, classkey) for val in obj] + if hasattr(obj, '__dict__'): + attrs = dict((key, todict(val, classkey)) for key, val in vars(obj).items()) + if classkey is not None and hasattr(obj, '__class__'): data[classkey] = obj.__class__.__name__ - return data - else: - return obj + return attrs + return obj From 6f190bb907642f9eb8bd58093c0d12ab90be118f Mon Sep 17 00:00:00 2001 From: Hilton Bristow Date: Thu, 27 Mar 2014 14:51:17 +1000 Subject: [PATCH 5/7] Generalized todict implementation --- modules/matlab/generator/parse_tree.py | 42 ++++++++++++-------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/modules/matlab/generator/parse_tree.py b/modules/matlab/generator/parse_tree.py index bb1d456658..7dfb6c1ba2 100644 --- a/modules/matlab/generator/parse_tree.py +++ b/modules/matlab/generator/parse_tree.py @@ -1,6 +1,12 @@ import collections from textwrap import fill from filters import * +try: + # Python 2.7+ + basestring +except NameError: + # Python 3.3+ + basestring = str class ParseTree(object): """ @@ -305,6 +311,7 @@ class Constant(object): ref is the constant a reference? ('*'/'&') default default value, required for constants """ + __slots__ = ['name', 'clss', 'tp', 'ref', 'const', 'default'] def __init__(self, name='', clss='', tp='', const=False, ref='', default=''): self.name = name self.clss = clss @@ -334,31 +341,20 @@ def constants(tree): for gen in constants(val): yield gen -def isstring(s): - """ - Check if variable is string representable (regular/unicode/raw) - in a Python 2 and 3 compatible manner - """ - try: - return isinstance(s, basestring) - except NameError: - return isinstance(s, str) -def todict(obj, classkey=None): +def todict(obj): """ - Convert the ParseTree to a dictionary, stripping all objects of their - methods and converting class names to strings + Recursively convert a Python object graph to sequences (lists) + and mappings (dicts) of primitives (bool, int, float, string, ...) """ - if isstring(obj): - return obj - if isinstance(obj, dict): - obj.update((key, todict(val, classkey)) for key, val in obj.items()) + if isinstance(obj, basestring): return obj - if isinstance(obj, collections.Iterable): - return [todict(val, classkey) for val in obj] - if hasattr(obj, '__dict__'): - attrs = dict((key, todict(val, classkey)) for key, val in vars(obj).items()) - if classkey is not None and hasattr(obj, '__class__'): - data[classkey] = obj.__class__.__name__ - return attrs + elif isinstance(obj, dict): + return dict((key, todict(val)) for key, val in obj.items()) + elif isinstance(obj, collections.Iterable): + return [todict(val) for val in obj] + elif hasattr(obj, '__dict__'): + return todict(vars(obj)) + elif hasattr(obj, '__slots__'): + return todict(dict((name, getattr(obj, name)) for name in getattr(obj, '__slots__'))) return obj From fc696a9ff3ef7bbeb2f7420cead255d950a7ba3b Mon Sep 17 00:00:00 2001 From: Hilton Bristow Date: Thu, 27 Mar 2014 14:52:23 +1000 Subject: [PATCH 6/7] Improved standalone importing behaviour and creation of nested directories --- modules/matlab/generator/gen_matlab.py | 27 +++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/modules/matlab/generator/gen_matlab.py b/modules/matlab/generator/gen_matlab.py index 9f0975d97b..36d588c92a 100644 --- a/modules/matlab/generator/gen_matlab.py +++ b/modules/matlab/generator/gen_matlab.py @@ -1,4 +1,8 @@ #!/usr/bin/env python +import sys, re, os, time +from string import Template +from parse_tree import ParseTree, todict, constants +from filters import * class MatlabWrapperGenerator(object): """ @@ -22,9 +26,14 @@ class MatlabWrapperGenerator(object): The output_dir specifies the directory to write the generated sources to. """ + # dynamically import the parsers + from jinja2 import Environment, FileSystemLoader + import hdr_parser + import rst_parser + # parse each of the files and store in a dictionary # as a separate "namespace" - parser = CppHeaderParser() + parser = hdr_parser.CppHeaderParser() rst = rst_parser.RstParser(parser) rst_parser.verbose = False rst_parser.show_warnings = False @@ -91,13 +100,13 @@ class MatlabWrapperGenerator(object): output_class_dir = output_dir+'/+cv' output_map_dir = output_dir+'/map' if not os.path.isdir(output_source_dir): - os.mkdir(output_source_dir) + os.makedirs(output_source_dir) if not os.path.isdir(output_private_dir): - os.mkdir(output_private_dir) + os.makedirs(output_private_dir) if not os.path.isdir(output_class_dir): - os.mkdir(output_class_dir) + os.makedirs(output_class_dir) if not os.path.isdir(output_map_dir): - os.mkdir(output_map_dir) + os.makedirs(output_map_dir) # populate templates for namespace in parse_tree.namespaces: @@ -168,7 +177,6 @@ if __name__ == "__main__": """ # parse the input options - import sys, re, os, time from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument('--jinja2') @@ -185,13 +193,6 @@ if __name__ == "__main__": sys.path.append(args.hdrparser) sys.path.append(args.rstparser) - from string import Template - from hdr_parser import CppHeaderParser - import rst_parser - from parse_tree import ParseTree, todict, constants - from filters import * - from jinja2 import Environment, FileSystemLoader - # create the generator mwg = MatlabWrapperGenerator() mwg.gen(args.moduleroot, args.modules, args.extra, args.outdir) From 61c22d5899f6535f06aaf84a30ba48dbd37e4967 Mon Sep 17 00:00:00 2001 From: Hilton Bristow Date: Thu, 27 Mar 2014 14:58:53 +1000 Subject: [PATCH 7/7] removed experimental slots --- modules/matlab/generator/parse_tree.py | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/matlab/generator/parse_tree.py b/modules/matlab/generator/parse_tree.py index 7dfb6c1ba2..a6a146a55f 100644 --- a/modules/matlab/generator/parse_tree.py +++ b/modules/matlab/generator/parse_tree.py @@ -311,7 +311,6 @@ class Constant(object): ref is the constant a reference? ('*'/'&') default default value, required for constants """ - __slots__ = ['name', 'clss', 'tp', 'ref', 'const', 'default'] def __init__(self, name='', clss='', tp='', const=False, ref='', default=''): self.name = name self.clss = clss