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 diff --git a/modules/java/generator/rst_parser.py b/modules/java/generator/rst_parser.py index f2363169be..750d6f0be8 100755 --- a/modules/java/generator/rst_parser.py +++ b/modules/java/generator/rst_parser.py @@ -1,5 +1,6 @@ #!/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", "softcascade", "superres"] verbose = False @@ -141,10 +142,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 +153,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 +312,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 +329,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 +352,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 +389,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 +406,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 +444,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 +465,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 +542,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 +633,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 +652,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 +744,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 +760,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/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/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/gen_matlab.py b/modules/matlab/generator/gen_matlab.py index 49e575099a..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: @@ -105,27 +114,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__": @@ -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) diff --git a/modules/matlab/generator/parse_tree.py b/modules/matlab/generator/parse_tree.py index daea53c2f2..a6a146a55f 100644 --- a/modules/matlab/generator/parse_tree.py +++ b/modules/matlab/generator/parse_tree.py @@ -1,6 +1,12 @@ -from string import join +import collections from textwrap import fill from filters import * +try: + # Python 2.7+ + basestring +except NameError: + # Python 3.3+ + basestring = str class ParseTree(object): """ @@ -74,7 +80,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 +100,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 +214,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 +234,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 +266,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): @@ -334,23 +340,20 @@ def constants(tree): for gen in constants(val): yield gen -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 isinstance(obj, dict): - for k in obj.keys(): - obj[k] = todict(obj[k], classkey) - return obj - elif hasattr(obj, "__iter__"): - 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() - if not callable(value) and not key.startswith('_')]) - if classkey is not None and hasattr(obj, "__class__"): - data[classkey] = obj.__class__.__name__ - return data - else: + if isinstance(obj, basestring): return obj + 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