def get_filename_from_import(module, output_folder=''): """Returns a valid filename with absolute path, that corresponds to the definition of module. The priority order is: - header files (extension == pyh) - python files (extension == py) """ filename_pyh = '{}.pyh'.format(module.replace('.', '/')) filename_py = '{}.py'.format(module.replace('.', '/')) if is_valid_filename_pyh(filename_pyh): return os.path.abspath(filename_pyh) if is_valid_filename_py(filename_py): return os.path.abspath(filename_py) folders = output_folder.split(""".""") for i in range(len(folders)): poss_dirname = os.path.join(*folders[:i + 1]) poss_filename_pyh = os.path.join(poss_dirname, filename_pyh) poss_filename_py = os.path.join(poss_dirname, filename_py) if is_valid_filename_pyh(poss_filename_pyh): return os.path.abspath(poss_filename_pyh) if is_valid_filename_py(poss_filename_py): return os.path.abspath(poss_filename_py) source = module if len(module.split(""".""")) > 1: # we remove the last entry, since it can be a pyh file source = """.""".join(i for i in module.split(""".""")[:-1]) _module = module.split(""".""")[-1] filename_pyh = '{}.pyh'.format(_module) filename_py = '{}.py'.format(_module) try: package = importlib.import_module(source) package_dir = str(package.__path__[0]) except: errors = Errors() errors.report(PYCCEL_UNFOUND_IMPORTED_MODULE, symbol=source, severity='fatal') filename_pyh = os.path.join(package_dir, filename_pyh) filename_py = os.path.join(package_dir, filename_py) if os.path.isfile(filename_pyh): return filename_pyh elif os.path.isfile(filename_py): return filename_py errors = Errors() errors.report(PYCCEL_UNFOUND_IMPORTED_MODULE, symbol=module, severity='fatal')
def __init__(self, inputs, **kwargs): BasicParser.__init__(self, **kwargs) # check if inputs is a file code = inputs if os.path.isfile(inputs): # we don't use is_valid_filename_py since it uses absolute path # file extension ext = inputs.split(""".""")[-1] if not ext in ['py', 'pyh']: errors = Errors() errors.report(INVALID_FILE_EXTENSION, symbol=ext, severity='fatal') errors.check() raise SystemExit(0) code = read_file(inputs) self._filename = inputs self._code = code try: code = self.code red = RedBaron(code) except Exception as e: errors = Errors() errors.report(INVALID_PYTHON_SYNTAX, symbol='\n' + str(e), severity='fatal') errors.check() raise SystemExit(0) red = fst_move_directives(red) self._fst = red self.parse(verbose=True)
def pyccel(files=None, openmp=None, openacc=None, output_dir=None, compiler='gfortran'): """ pyccel console command. """ parser = MyParser(description='pyccel command line') parser.add_argument('files', metavar='N', type=str, nargs='+', help='a Pyccel file') # ... compiler syntax, semantic and codegen group = parser.add_argument_group('Pyccel compiling stages') group.add_argument('-x', '--syntax-only', action='store_true', help='Using pyccel for Syntax Checking') group.add_argument('-e', '--semantic-only', action='store_true', help='Using pyccel for Semantic Checking') group.add_argument('-t', '--convert-only', action='store_true', help='Converts pyccel files only without build') # ... # ... backend compiler options group = parser.add_argument_group('Backend compiler options') group.add_argument('--compiler', type=str, \ help='Used compiler') group.add_argument('--fflags', type=str, \ help='Fortran compiler flags.') group.add_argument('--debug', action='store_true', \ help='compiles the code in a debug mode.') group.add_argument('--include', type=str, \ help='path to include directory.') group.add_argument('--libdir', type=str, \ help='path to lib directory.') group.add_argument('--libs', type=str, \ help='list of libraries to link with.') group.add_argument('--output', type=str, default = '',\ help='folder in which the output is stored.') group.add_argument('--prefix', type=str, default = '',\ help='add prefix to the generated file.') group.add_argument('--prefix-module', type=str, default = '',\ help='add prefix module name.') group.add_argument('--language', type=str, help='target language') # ... # ... Accelerators group = parser.add_argument_group('Accelerators options') group.add_argument('--openmp', action='store_true', \ help='uses openmp') group.add_argument('--openacc', action='store_true', \ help='uses openacc') # ... # ... Other options group = parser.add_argument_group('Other options') group.add_argument('--verbose', action='store_true', \ help='enables verbose mode.') group.add_argument('--developer-mode', action='store_true', \ help='shows internal messages') # ... # TODO move to another cmd line parser.add_argument('--analysis', action='store_true', \ help='enables code analysis mode.') # ... # ... args = parser.parse_args() # ... # ... if not files: files = args.files if args.compiler: compiler = args.compiler if not openmp: openmp = args.openmp if not openacc: openacc = args.openacc if args.convert_only or args.syntax_only or args.semantic_only: compiler = None # ... # ... if not files: raise ValueError("a python filename must be provided.") if len(files) > 1: raise ValueError('Expecting one single file for the moment.') # ... filename = files[0] # ... report error if os.path.isfile(filename): # we don't use is_valid_filename_py since it uses absolute path # file extension ext = filename.split('.')[-1] if not(ext in ['py', 'pyh']): errors = Errors() errors.report(INVALID_FILE_EXTENSION, symbol=ext, severity='fatal') errors.check() raise SystemExit(0) else: # we use Pyccel error manager, although we can do it in other ways errors = Errors() errors.report(INVALID_FILE_DIRECTORY, symbol=filename, severity='fatal') errors.check() raise SystemExit(0) # ... if compiler: if _which(compiler) is None: raise ValueError('Could not find {0}'.format(compiler)) accelerator = None if openmp: accelerator = "openmp" if openacc: accelerator = "openacc" debug = args.debug verbose = args.verbose include = args.include fflags = args.fflags libdir = args.libdir libs = args.libs output_folder = args.output prefix = args.prefix prefix_module = args.prefix_module language = args.language if (len(output_folder)>0 and output_folder[-1]!='/'): output_folder+='/' if not include: include = [] if not libdir: libdir = [] if not libs: libs = [] # ... # ... if args.developer_mode: # this will initialize the singelton ErrorsMode # making this settings available everywhere err_mode = ErrorsMode() err_mode.set_mode('developer') # ... # ... from pyccel.parser import Parser from pyccel.codegen import Codegen if args.syntax_only: pyccel = Parser(filename) ast = pyccel.parse() elif args.semantic_only: pyccel = Parser(filename) ast = pyccel.parse() settings = {} ast = pyccel.annotate(**settings) elif args.convert_only: pyccel = Parser(filename) ast = pyccel.parse() settings = {} if args.language: settings['language'] = args.language ast = pyccel.annotate(**settings) name = os.path.basename(filename) name = os.path.splitext(name)[0] codegen = Codegen(ast, name) settings['prefix_module'] = prefix_module code = codegen.doprint(**settings) if prefix: name = '{prefix}{name}'.format(prefix=prefix, name=name) codegen.export(output_folder+name) for son in pyccel.sons: if 'print' in son.metavars.keys(): name = son.filename.split('/')[-1].strip('.py') name = 'mod_'+name codegen = Codegen(son.ast, name) code = codegen.doprint() codegen.export() elif args.analysis: # TODO move to another cmd line from pyccel.complexity.arithmetic import OpComplexity complexity = OpComplexity(filename) print(" arithmetic cost ~ " + str(complexity.cost())) else: # TODO shall we add them in the cmd line? modules = [] binary = None execute_pyccel(filename, compiler=compiler, fflags=fflags, debug=False, verbose=verbose, accelerator=accelerator, include=include, libdir=libdir, modules=modules, libs=libs, binary=binary, output=output_folder)