Initial commit

This commit is contained in:
Geoff Doty 2018-12-05 13:27:13 -05:00
commit 3e7d0840f2
8 changed files with 223 additions and 0 deletions

35
.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
*.py[cod]
# C extensions
*.so
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
__pycache__
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
nosetests.xml
# Translations
*.mo
# Mr Developer
.vscode
.venv

120
README.md Normal file
View File

@ -0,0 +1,120 @@
# Python Library Packaging
> SOURCE: https://python-packaging.readthedocs.io/en/latest/minimal.html
This is a simple python packaging example
## Project Structure
```
py-lib
py-lib/
__init__py
docs/ <-- optional
README.md
requirements.txt
setup.py
tests/ <-- optional
```
> tests are something you **should** do, but are NOT a **must** to publish
Now we can install the package locally (for use on our system), with:
```$ pip install .```
We can also install the package with a symlink, so that changes to the source files will be immediately available to other users of the package on our system:
```$ pip install -e .```
Anywhere else in our system using the same Python, we can do this now:
```
>>> import funniest
>>> print funniest.joke()
```
## Publishing On PyPI
The setup.py script is also our main entrypoint to register the package name on PyPI and upload source distributions.
To “register” the package (this will reserve the name, upload package metadata, and create the pypi.python.org webpage):
$ python setup.py register
If you havent published things on PyPI before, youll need to create an account by following the steps provided at this point.
At this point you can view the (very minimal) page on PyPI describing funniest:
http://pypi.python.org/pypi/funniest/0.1
Although users can follow the URL link to find our git repository, well probably want to upload a source distribution so that the package can be installed without cloning the repository. This will also enable automated installation and dependency resolution tools to install our package.
First create a source distribution with:
$ python setup.py sdist
This will create dist/funniest-0.1.tar.gz inside our top-level directory. If you like, copy that file to another host and try unpacking it and install it, just to verify that it works for you.
That file can then be uploaded to PyPI with:
$ python setup.py sdist upload
You can combine all of these steps, to update metadata and publish a new build in a single step:
$ python setup.py register sdist upload
For a detailed list of all available setup.py commands, do:
$ python setup.py --help-commands
Installing the Package
At this point, other consumers of this package can install the package with pip:
$ pip install funniest
They can specify it as a dependency for another package, and it will be automatically installed when that package is installed (well get to how to do that later).
Adding Additional Files
Most of the time well want more than one file containing code inside of our module. Additional files should always be added inside the inner funniest directory.
For example, lets move our one function to a new text submodule, so our directory hierarchy looks like this:
```
funniest/
funniest/
__init__.py
text.py
setup.py
In __init__.py:
from .text import joke
In text.py:
def joke():
return (u'Wenn ist das Nunst\u00fcck git und Slotermeyer? Ja! ... '
u'Beiherhund das Oder die Flipperwaldt gersput.')
```
All additional Python code belongs in the funniest/funniest/ directory.
Ignoring Files (.gitignore, etc)
Theres one more thing well probably want in a bare bones package: a .gitignore file, or the equivalent for other SCMs. The Python build system creates a number of intermediary files well want to be careful to not commit to source control. Heres an example of what .gitignore should look like for funniest:
**Compiled python modules.**
*.pyc
**Setuptools distribution folder.**
/dist/
**Python egg metadata, regenerated from source files by setuptools.**
/*.egg-info
Thats All You Need
The structure described so far is all thats necessary to create reusable simple packages with no packaging bugs. If every published Python tool or library used followed these rules, the world would be a better place.

0
docs/.gitkeep Normal file
View File

19
py-lib/__init__.py Normal file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Module Docstring
"""
__author__ = "Your Name"
__version__ = "0.1.0"
__license__ = "MIT"
def main():
""" Main entry point of the app """
print "hello world"
if __name__ == "__main__":
""" This is executed when run from the command line """
main()

0
requirements.txt Normal file
View File

11
setup.py Normal file
View File

@ -0,0 +1,11 @@
from setuptools import setup
setup(name='py-lib',
version='0.1',
description='boilerplate for new libraries',
url='http://github.com/n2geoff/py-lib',
author='You',
author_email='you@example.com',
license='MIT',
packages=['py-lib'],
zip_safe=False)

0
tests/__init__.py Normal file
View File

38
tests/test_main.py Normal file
View File

@ -0,0 +1,38 @@
"""
This file demonstrates common uses for the Python unittest module
https://docs.python.org/2/library/unittest.html
"""
import random
import unittest
class TestSequenceFunctions(unittest.TestCase):
""" This is one of potentially many TestCases """
def setUp(self):
self.seq = list(range(10))
def test_shuffle(self):
""" make sure the shuffled sequence does not lose any elements """
random.shuffle(self.seq)
self.seq.sort()
self.assertEqual(self.seq, list(range(10)))
# should raise an exception for an immutable sequence
self.assertRaises(TypeError, random.shuffle, (1, 2, 3))
def test_choice(self):
""" test a choice """
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
def test_sample(self):
""" test that an exception is raised """
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
if __name__ == '__main__':
unittest.main()