<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Example of Pythran Usage Within a Full Project
This notebook covers the creation of a simple, distutils-powered, project that ships a pythran kernel.
But first some cleanup
Step2:  Project layout
The Pythran file is really dumb.
The expected layout is
Step4:  And so is the __init__.py file.
Step5:  The setup.py file contains the classical metadata, plus a special header. this header basically states if pythran is available, use it, otherwise fallback to the python file.
Step6:  Running setup.py
With the described configuration, the normal python setup.py targets should « just work ».
If pythran is in the path, it is used to generate the alternative c++ extension when building a source release. Note the hello.cpp!
Step7:  But if pythran is no longer in the PYTHONPATH, the installation does not fail
Step8:  In case of binary distribution, the native module is generated alongside the original source.
Step9:  And if pythran is not in the PYTHONPATH, this still work \o/
<ASSISTANT_TASK:>
Python Code:
!rm -rf hello setup.py && mkdir hello
Explanation: Example of Pythran Usage Within a Full Project
This notebook covers the creation of a simple, distutils-powered, project that ships a pythran kernel.
But first some cleanup
End of explanation
%%file hello/hello.py
#pythran export hello()
def hello():
    
    Wave hello.
    
    print("Hello from Pythran o/")
Explanation: Project layout
The Pythran file is really dumb.
The expected layout is:
setup.py
hello/
  +---- __init__.py
  +---- hello.py
End of explanation
%%file hello/__init__.py
Hello package, featuring a Pythran kernel.
from hello import hello
Explanation: And so is the __init__.py file.
End of explanation
%%file setup.py
from distutils.core import setup
try:
    from pythran.dist import PythranExtension, PythranBuildExt
    setup_args = {
        'cmdclass': {"build_ext": PythranBuildExt},
        'ext_modules': [PythranExtension('hello.hello', sources = ['hello/hello.py'])],
    }
except ImportError:
    print("Not building Pythran extension")
    setup_args = {}
          
setup(name = 'hello',
      version = '1.0',
      description = 'Yet another demo package',
      packages = ['hello'],
      **setup_args)
Explanation: The setup.py file contains the classical metadata, plus a special header. this header basically states if pythran is available, use it, otherwise fallback to the python file.
End of explanation
%%sh
rm -rf build dist
python setup.py sdist 2>/dev/null 1>/dev/null
tar tf dist/hello-1.0.tar.gz | grep -E 'hello/hello.(py|cpp)' -o | sort
Explanation: Running setup.py
With the described configuration, the normal python setup.py targets should « just work ».
If pythran is in the path, it is used to generate the alternative c++ extension when building a source release. Note the hello.cpp!
End of explanation
%%sh
rm -rf build dist
PYTHONPATH= python setup.py sdist 2>/dev/null 1>/dev/null
tar tf dist/hello-1.0.tar.gz | grep -E 'hello/hello.py' -o
Explanation: But if pythran is no longer in the PYTHONPATH, the installation does not fail: the regular Python source can still be used.
End of explanation
%%sh
rm -rf build dist
python setup.py bdist 2>/dev/null 1>/dev/null
tar tf dist/hello-1.0.linux-x86_64.tar.gz | grep -E 'hello/hello.(py|cpp)' -o
Explanation: In case of binary distribution, the native module is generated alongside the original source.
End of explanation
%%sh
rm -rf build dist
PYTHONPATH= python setup.py bdist 2>/dev/null 1>/dev/null
tar tf dist/hello-1.0.linux-x86_64.tar.gz | grep -E 'hello/hello.py' -o
Explanation: And if pythran is not in the PYTHONPATH, this still work \o/
End of explanation
<END_TASK>