#
##
##  This file is part of pyFormex 1.0.5  (Sat Feb 16 10:40:32 CET 2019)
##  pyFormex is a tool for generating, manipulating and transforming 3D
##  geometrical models by sequences of mathematical operations.
##  Home page: http://pyformex.org
##  Project page:  http://savannah.nongnu.org/projects/pyformex/
##  Copyright 2004-2018 (C) Benedict Verhegghe (benedict.verhegghe@ugent.be)
##  Distributed under the GNU General Public License version 3 or later.
##
##  This program is free software: you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation, either version 3 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with this program.  If not, see http://www.gnu.org/licenses/.
##
"""pyFormex compatibility module for Python3.x

The compatibility modules for different Python versions are intended
to wrap code changes between the versions into functions located at
a single place.

Note that we can not implement this as a single module and test for
the Python version inside that module. The differences between the
versions might cause compilation to fail.
"""
from __future__ import absolute_import, division, print_function

py3_warning = """
#####################################################################
##  Warning! This is an experimental Python3 version of pyFormex.  ##
##  While most things will work correctly, you should be aware of  ##
##  this and pay extra attention to warnings and messages.         ##
##  For production purposes, we recommend the Python2 version.     ##
#####################################################################
"""
print(py3_warning)

import sys
if (sys.hexversion & 0xFFFF0000) == 0x03010000:

    # Python 3.1 has no callable(), let's define it here
    import collections
    def callable(f):
        return isinstance(f, collections.Callable)
    __builtins__['callable'] = callable


zip = __builtins__['zip']
round = __builtins__['round']
__builtins__['unicode'] = str

def to_str(s):
    """Silently convert bytes to str.

    The input is either str or bytes. The output is always str.
    """
    if isinstance(s,str):
        return s
    elif isinstance(s,bytes):
        return bytes.decode(s)
    else:
        raise valueError("Input should be str or bytes")


import pickle


def execFile(f,*args,**kargs):
    return exec(compile(open(f,'r').read(), f, 'exec'),*args,**kargs)


def userInput(*args,**kargs):
    return input(*args,**kargs)


# Print a string only in Python3
print3 = print

def isFile(o):
    """Test if an object is a file"""
    import io
    return isinstance(o,io.IOBase)


def isString(o):
    """Test if an object is a string (ascii or unicode)"""
    return isinstance(o,(str,bytes))



def findModuleSource(module):
    """Find the path of the source file of a module

    module is either an imported module (pkg.mod) or a string with the module
    name ('pkg.mod'), imported or not.
    Returns the source file from which the module was/would be loaded when
    imported.
    Raises an error if the module can not be imported or
    does not have a source file.
    """
    import importlib.util
    if isinstance(module, str):
        spec = importlib.util.find_spec(module)
        if spec is None:
            raise ImportError("Can't find module {}".format(module))
    else:
        spec = module.__spec__
    return spec.origin

# End
