Skip to content

Commit

Permalink
fix #42: unify README and module doc
Browse files Browse the repository at this point in the history
  • Loading branch information
mmckerns committed Jul 6, 2022
1 parent f1918f5 commit 09b6c5b
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 204 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ include README*
include MANIFEST.in
include pyproject.toml
include tox.ini
include version.py
recursive-include docs *
recursive-include ppft *
recursive-include pp *
Expand Down
5 changes: 3 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,13 @@

# extension config
github_project_url = "https://github.com/uqfoundation/ppft"
autoclass_content= 'both'
autoclass_content = 'both'
autodoc_typehints = 'description'
napoleon_include_init_with_doc = True
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = True
napoleon_use_param = False
napoleon_use_ivar = True
napoleon_use_param = True

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down
180 changes: 17 additions & 163 deletions ppft/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,169 +6,22 @@
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/ppft/blob/master/LICENSE

# author, version, license, and long description #FIXME: common.__version__
__version__ = '1.7.6.6.dev0'
__author__ = 'Mike McKerns'
# author, version, license, and long description
try: # the package is installed
from .__info__ import __version__, __author__, __doc__, __license__
except: # pragma: no cover
import os
import sys
parent = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
sys.path.append(parent)
# get distribution meta info
from version import (__version__, __author__,
get_license_text, get_readme_as_rst)
__license__ = get_license_text(os.path.join(parent, 'LICENSE'))
__license__ = "\n%s" % __license__
__doc__ = get_readme_as_rst(os.path.join(parent, 'README.md'))
del os, sys, parent, get_license_text, get_readme_as_rst

__doc__ = """
-------------------------------------
ppft: distributed and parallel python
-------------------------------------
About Ppft
==========
``ppft`` is a friendly fork of Parallel Python (``pp``). ``ppft`` extends Parallel Python to provide packaging and distribution with ``pip`` and ``setuptools``, support for python 3, and enhanced serialization using ``dill.source``. ``ppft`` uses Parallel Python to provide mechanisms for the parallel execution of python code on SMP (systems with multiple processors or cores) and clusters (computers connected via network).
Software written in python finds applications in a broad range of the categories including business logic, data analysis, and scientific calculations. This together with wide availability of SMP computers (multi-processor or multi-core) and clusters (computers connected via network) on the market create the demand in parallel execution of python code.
The most common way to write parallel applications for SMP computers is to use threads. However, the python interpreter uses the GIL (Global Interpreter Lock) for internal bookkeeping, where the GIL only allows one python byte-code instruction to execute at a time, even on an SMP computer. Parallel Python overcomes this limitation, and provides a simple way to write parallel python applications. Internally, processes and IPC (Inter Process Communications) are used to organize parallel computations. Parallel Python is written so that the details and complexity of IPC are handled internally, and the calling application just submits jobs and retrieves the results. Software written with Parallel Python works in parallel on many computers connected via a local network or the Internet. Cross-platform portability and dynamic load-balancing allows Parallel Python to parallelize computations efficiently even on heterogeneous and multi-platform clusters. Visit http://www.parallelpython.com for further information on Parallel Python.
``ppft`` is part of ``pathos``, a python framework for heterogeneous computing.
``ppft`` is in active development, so any user feedback, bug reports, comments,
or suggestions are highly appreciated. A list of issues is located at https://github.com/uqfoundation/ppft/issues, with a legacy list maintained at https://uqfoundation.github.io/project/pathos/query.
Major Features
==============
``ppft`` provides:
- parallel execution of python code on SMP and clusters
- easy-to-understand job-based parallelization
- automatic detection of the number of effective processors
- dynamic processor allocation (at runtime)
- low overhead for jobs with the same function (through transparent caching)
- dynamic load balancing (jobs are distributed at runtime)
- fault-tolerance (if a node fails, tasks are rescheduled on the others)
- auto-discovery of computational resources
- dynamic allocation of computational resources
- SHA based authentication for network connections
- enhanced serialization, using ``dill.source``
Current Release
===============
The latest released version of ``ppft`` is available from:
https://pypi.org/project/ppft
``ppft`` is distributed under a 3-clause BSD license, and is a fork of ``pp-1.6.6``.
Development Version
===================
You can get the latest development version with all the shiny new features at:
https://github.com/uqfoundation
If you have a new contribution, please submit a pull request.
Installation
============
``ppft`` can be installed with ``pip``::
$ pip install ppft
To include enhanced serialization, using ``dill.source``, install::
$ pip install ppft[dill]
If Parallel Python is already installed, it should be uninstalled before ``ppft`` is installed -- otherwise, ``import pp`` may point to the original and not to the ``ppft`` fork.
Requirements
============
``ppft`` requires:
- ``python`` (or ``pypy``), **>=3.7**
- ``setuptools``, **>=42**
Optional requirements:
- ``dill``, **>=0.3.5.1**
More Information
================
Probably the best way to get started is to look at the documentation at
http://ppft.rtfd.io. Also, you can see a set of example scripts in
``ppft.tests``. You can run the test suite with ``python -m ppft.tests``.
``ppft`` will create and execute jobs on local workers (automatically created
using ``python -u -m ppft``). Additionally, remote servers can be created with
``ppserver`` (or ``python -m ppft.server``), and then jobs can be distributed
to remote workers. See ``--help`` for more details on how to configure a server.
Please feel free to submit a ticket on github, or ask a question on
stackoverflow (**@Mike McKerns**). If you would like to share how you use
``ppft`` in your work, please send an email (to **mmckerns at uqfoundation dot org**).
Citation
========
If you use ``ppft`` to do research that leads to publication, we ask that you
acknowledge use of ``ppft`` by citing the following in your publication::
M.M. McKerns, L. Strand, T. Sullivan, A. Fang, M.A.G. Aivazis,
"Building a framework for predictive science", Proceedings of
the 10th Python in Science Conference, 2011;
http://arxiv.org/pdf/1202.1056
Michael McKerns and Michael Aivazis,
"pathos: a framework for heterogeneous computing", 2010- ;
https://uqfoundation.github.io/project/pathos
Please see https://uqfoundation.github.io/project/pathos or
http://arxiv.org/pdf/1202.1056 for further information.
"""

__license__ = """
Copyright (c) 2015-2016 California Institute of Technology.
Copyright (c) 2016-2022 The Uncertainty Quantification Foundation.
All rights reserved.
This software forks the python package "pp". Licence and copyright
information for pp can be found in "COPYING".
This software is available subject to the conditions and terms laid
out below. By downloading and using this software you are agreeing
to the following conditions.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met::
- Redistribution of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistribution in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentations and/or other materials provided with the distribution.
- Neither the names of the copyright holders nor the names of any of
the contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""

from ._pp import *
from ._pp import _USE_SUBPROCESS, _Task, _Worker, _RWorker, _Statistics
Expand All @@ -188,6 +41,7 @@ def citation():
print (__doc__[-491:-118])
return

copyright = __license__[1:127] #FIXME: near-duplicate in common.copyright
copyright = """Copyright (c) 2005-2012 Vitalii Vanovschi.\n"""
copyright += __license__[1:127] #XXX: the 'same' as ppft.common.copyright

# EOF
12 changes: 11 additions & 1 deletion ppft/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,17 @@ def b_(string):
copyright = """Copyright (c) 2005-2012 Vitalii Vanovschi.
Copyright (c) 2015-2016 California Institute of Technology.
Copyright (c) 2016-2022 The Uncertainty Quantification Foundation."""
__version__ = version = "1.7.6.6" # use release/target version only
try: # the package is installed
from .__info__ import __version__ as version
except: # pragma: no cover
import os
import sys
parent = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
sys.path.append(parent)
# get distribution meta info
from version import __version__ as version
del os, sys, parent
__version__ = version = version.rstrip('.dev0') # release/target version only

def start_thread(name, target, args=(), kwargs={}, daemon=True):
"""Starts a thread"""
Expand Down
51 changes: 13 additions & 38 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,16 @@

# get distribution meta info
here = os.path.abspath(os.path.dirname(__file__))
meta_fh = open(os.path.join(here, 'ppft/__init__.py'))
try:
meta = {}
for line in meta_fh:
if line.startswith('__version__'):
VERSION = line.split()[-1].strip("'").strip('"')
break
meta['VERSION'] = VERSION
for line in meta_fh:
if line.startswith('__author__'):
AUTHOR = line.split(' = ')[-1].strip().strip("'").strip('"')
break
meta['AUTHOR'] = AUTHOR
LONG_DOC = ""
DOC_STOP = "FAKE_STOP_12345"
for line in meta_fh:
if LONG_DOC:
if line.startswith(DOC_STOP):
LONG_DOC = LONG_DOC.strip().strip("'").strip('"').lstrip()
break
else:
LONG_DOC += line
elif line.startswith('__doc__'):
DOC_STOP = line.split(' = ')[-1]
LONG_DOC = "\n"
meta['LONG_DOC'] = LONG_DOC
finally:
meta_fh.close()
sys.path.append(here)
from version import (__version__, __author__, __contact__ as AUTHOR_EMAIL,
get_license_text, get_readme_as_rst, write_info_file)
LICENSE = get_license_text(os.path.join(here, 'LICENSE'))
README = get_readme_as_rst(os.path.join(here, 'README.md'))

# get version numbers, long_description, etc
AUTHOR = meta['AUTHOR']
VERSION = meta['VERSION']
LONG_DOC = meta['LONG_DOC'] #FIXME: near-duplicate of README.md
#LICENSE = meta['LICENSE'] #FIXME: duplicate of LICENSE
AUTHOR_EMAIL = '[email protected]'
# write meta info file
write_info_file(here, 'ppft', doc=README, license=LICENSE,
version=__version__, author=__author__)
del here, get_license_text, get_readme_as_rst, write_info_file

# check if setuptools is available
try:
Expand All @@ -64,12 +39,12 @@
# build the 'setup' call
setup_kwds = dict(
name='ppft',
version=VERSION,
version=__version__,
description='distributed and parallel python',
long_description = LONG_DOC,
author = AUTHOR,
long_description = README.strip(),
author = __author__,
author_email = AUTHOR_EMAIL,
maintainer = AUTHOR,
maintainer = __author__,
maintainer_email = AUTHOR_EMAIL,
license = '3-clause BSD',
platforms = ['Linux', 'Windows', 'Mac'],
Expand Down
78 changes: 78 additions & 0 deletions version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2022 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/ppft/blob/master/LICENSE

__version__ = '1.7.6.6.dev0'
__author__ = 'Mike McKerns'
__contact__ = '[email protected]'


def get_license_text(filepath):
"open the LICENSE file and read the contents"
try:
LICENSE = open(filepath).read()
except:
LICENSE = ''
return LICENSE


def get_readme_as_rst(filepath):
"open the README file and read the markdown as rst"
try:
fh = open(filepath)
name, null = fh.readline().rstrip(), fh.readline()
tag, null = fh.readline(), fh.readline()
tag = "%s: %s" % (name, tag)
split = '-'*(len(tag)-1)+'\n'
README = ''.join((null,split,tag,split,'\n'))
skip = False
for line in fh:
if line.startswith('['):
continue
elif skip and line.startswith(' http'):
README += '\n' + line
elif line.startswith('* '):
README += line.replace('* ',' - ',1)
elif line.startswith('-'):
README += line.replace('-','=') + '\n'
else:
README += line
skip = line.endswith(':\n')
fh.close()
except:
README = ''
return README


def write_info_file(dirpath, modulename, **info):
"""write the given info to 'modulename/__info__.py'
info expects:
doc: the module's long_description
version: the module's version string
author: the module's author string
license: the module's license contents
"""
import os
infofile = os.path.join(dirpath, '%s/__info__.py' % modulename)
header = '''#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2022 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/%s/blob/master/LICENSE
''' % modulename #XXX: author and email are hardwired in the header
doc = info.get('doc', None)
version = info.get('version', None)
author = info.get('author', None)
license = info.get('license', None)
with open(infofile, 'w') as fh:
fh.write(header)
if doc is not None: fh.write("'''%s'''\n\n" % doc)
if version is not None: fh.write("__version__ = %r\n" % version)
if author is not None: fh.write("__author__ = %r\n\n" % author)
if license is not None: fh.write("__license__ = '''\n%s'''\n" % license)
return

0 comments on commit 09b6c5b

Please sign in to comment.