diff --git a/.bumpversion.cfg b/.bumpversion.cfg new file mode 100644 index 00000000..de32cc4c --- /dev/null +++ b/.bumpversion.cfg @@ -0,0 +1,14 @@ +[bumpversion] +current_version = 0.6.1 +commit = False +tag = True +message = Bump up to version {new_version}. + +[bdist_wheel] +python-tag = py3 + +[bumpversion:file:coxeter/__init__.py] + +[bumpversion:file:doc/source/conf.py] + +[bumpversion:file:pyproject.toml] diff --git a/.circleci/config.yml b/.circleci/config.yml index ed3ce914..48b70bd2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -21,7 +21,7 @@ jobs: - run: &install name: Install package command: | - python -m pip install .[test] --progress-bar off --user + python -m pip install ".[tests]" --progress-bar off --user - run: &run-tests name: Run tests diff --git a/.gitignore b/.gitignore index 028cfa56..c9c11ac1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ *~ *.swp -# Packages +# OS Specific +.DS_Store + +# Packaging *.egg *.egg-info* dist @@ -15,8 +18,25 @@ develop-eggs .installed.cfg lib lib64 + +# Optimization __pycache__ -.hypothesis *.pyc + +# Unit tests +.coverage +.coverage.* +.hypothesis +.hypothesis/ +.pytest_cache/ + +# Documentation doc/source/bibtex.json + +# Development tools .ipynb_checkpoints +.spyderproject +.spyproject +*.sublime-workspace +.vscode +.code-workspace diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ec252e30..ddae7731 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -56,11 +56,6 @@ repos: hooks: - id: nbqa-pyupgrade args: - - --nbqa-mutate - --py36-plus - id: nbqa-isort - args: - - --nbqa-mutate - id: nbqa-black - args: - - --nbqa-mutate diff --git a/README.rst b/README.rst index d53be3d3..ff9b0e3e 100644 --- a/README.rst +++ b/README.rst @@ -78,7 +78,15 @@ To install from source, execute: git clone https://github.com/glotzerlab/coxeter.git cd coxeter - python setup.py install --user + +To install the package, choose one of the following: + +.. code:: bash + + pip install . # Install with no additional dependencies + pip install .[tests] # RECOMMENDED: Install with dependencies required to run pytests + pip install .[tests,doc] # Install all dependencies required to develop for coxeter + Requirements ~~~~~~~~~~~~ @@ -94,19 +102,19 @@ Testing The package is currently tested for Python >= 3.8 on Unix-like systems. Continuous integrated testing is performed using CircleCI on these Python versions. -To run the packaged unit tests, execute the following line from the root of the repository: +First, install the packages required to test coxeter (if not already done): .. code:: bash - pytest + pip install -r tests/requirements.txt -To check test coverage, make sure the coverage module is installed: +To run the packaged unit tests, execute the following line from the root of the repository: .. code:: bash - pip install coverage + pytest -and then run the packaged unit tests with the coverage module: +To run the packaged unit tests with the coverage module: .. code:: bash @@ -115,13 +123,17 @@ and then run the packaged unit tests with the coverage module: Building Documentation ---------------------- -Documentation for coxeter is written in `reStructuredText `__ and compiled using `Sphinx `__. -To build the documentation, first install Sphinx: +Documentation for coxeter is written in `reStructuredText `_ and compiled using `Sphinx `__. +To build the documentation, first install Sphinx and the other required packges: .. code:: bash cd doc pip install -r requirements.txt + conda install -c conda-forge fresnel + +.. warning:: + The `fresnel `_ package on conda forge must be used. The PyPI package *fresnel* is different and will not function properly. You can then use Sphinx to create the actual documentation in either PDF or HTML form by running the following commands in the coxeter root directory: diff --git a/coxeter/families/common.py b/coxeter/families/common.py index 4585b8d3..ec38196c 100644 --- a/coxeter/families/common.py +++ b/coxeter/families/common.py @@ -75,7 +75,7 @@ def make_vertices(cls, n): PlatonicFamily = TabulatedGSDShapeFamily.from_json_file( os.path.join(_DATA_FOLDER, "platonic.json"), classname="PlatonicFamily", - docstring="""The family of Platonic solids. + docstring="""The family of Platonic solids (5 total). The following parameters are required by this class: @@ -88,6 +88,7 @@ def make_vertices(cls, n): os.path.join(_DATA_FOLDER, "archimedean.json"), classname="ArchimedeanFamily", docstring="""The family of Archimedean solids (13 total). + The following parameters are required by this class: - name: The name of the ArchimedeanFamily solid. Options are "Cuboctahedron", \ "Icosidodecahedron", "Truncated Tetrahedron", "Truncated Octahedron", \ @@ -101,8 +102,9 @@ def make_vertices(cls, n): CatalanFamily = TabulatedGSDShapeFamily.from_json_file( os.path.join(_DATA_FOLDER, "catalan.json"), classname="CatalanFamily", - docstring="""The family of Catalan solids, also known as Archimedean duals + docstring="""The family of Catalan solids, also known as Archimedean duals \ (13 total). + The following parameters are required by this class: - name: The name of the CatalanFamily solid. Options are "Deltoidal \ Hexecontahedron", "Deltoidal Icositetrahedron", "Disdyakis \ @@ -117,10 +119,12 @@ def make_vertices(cls, n): JohnsonFamily = TabulatedGSDShapeFamily.from_json_file( os.path.join(_DATA_FOLDER, "johnson.json"), classname="JohnsonFamily", - docstring="""The family of Johnson solids (92 total). + docstring="""The family of Johnson solids, as enumerated in \ + :cite:`Johnson1966` (92 total). + The following parameters are required by this class: - name: The name of the JohnsonFamily solid. A full list is available in \ - 10.1126/science.1220869: :cite:`Damasceno2012`. In general, shape names \ + :cite:`Johnson1966`. In general, shape names \ should have the first character of each word capitalized, with spaces \ between words (e.g. "Elongated Triangular Cupola"). Pyramids and \ dipyramids are named from their base polygon (e.g. "Square Pyramid" \ @@ -133,7 +137,8 @@ def make_vertices(cls, n): os.path.join(_DATA_FOLDER, "pyramid_dipyramid.json"), classname="PyramidDipyramidFamily", docstring="""The family of regular equilateral pyramids and dipyramids (6 total). -The following parameters are required by this class: + + The following parameters are required by this class: - name: The name of the pyramid or dipyramid. Options are "Triangular Pyramid", \ "Square Pyramid", "Pentagonal Pyramid", "Triangular Dipyramid", \ "Square Dipyramid", and "Pentagonal Dipyramid". @@ -144,7 +149,8 @@ def make_vertices(cls, n): os.path.join(_DATA_FOLDER, "prism_antiprism.json"), classname="PrismAntiprismFamily", docstring="""The family of n-gonal prisms and antiprisms with n∈[3,10] (16 total). -The following parameters are required by this class: + + The following parameters are required by this class: - name: The name of the prism or antiprism. Options for prisms are \ "Triangular Prism", "Square Prism", "Pentagonal Prism", "Hexagonal Prism", \ "Heptagonal Prism", "Octagonal Prism", "Nonagonal Prism", and \ diff --git a/doc/requirements.txt b/doc/requirements.txt index 59d3572f..00023fbe 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,9 +1,10 @@ numpy rowan>=1.2 scipy -jupyter +sphinx<=5.3.0 sphinxcontrib-bibtex>=2.0.0 -autodocsumm +sphinx_rtd_theme nbsphinx -fresnel +autodocsumm +jupyter matplotlib diff --git a/doc/source/coxeter.bib b/doc/source/coxeter.bib index 9ea9e977..15a4e432 100644 --- a/doc/source/coxeter.bib +++ b/doc/source/coxeter.bib @@ -50,6 +50,17 @@ @article{Chen2014 doi = {10.1103/PhysRevX.4.011024}, } +@article{Johnson1966, +title={Convex Polyhedra with Regular Faces}, +author={Johnson, Norman W.}, +journal={Canadian Journal of Mathematics}, +volume={18}, +pages={169–200}, +year={1966}, +publisher={Cambridge University Press}, +doi={10.4153/cjm-1966-021-8}, +} + @article{Damasceno2012, author = {Damasceno, Pablo F. and Engel, Michael and Glotzer, Sharon C.}, title = {Crystalline Assemblies and Densest Packings of a Family of Truncated Tetrahedra and the Role of Directional Entropic Forces}, diff --git a/doc/source/development.rst b/doc/source/development.rst index 3f47dd05..4e30863c 100644 --- a/doc/source/development.rst +++ b/doc/source/development.rst @@ -39,6 +39,7 @@ To provide a reasonable balance between a high level of backwards compatibility To avoid having commits fail in case you forget to run this, you can set up a git pre-commit hook using `pre-commit`_: .. code-block:: bash + pre-commit install diff --git a/pyproject.toml b/pyproject.toml index a0baa1b8..da4f3ef0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,49 @@ +[build-system] +requires = ["setuptools","wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "coxeter" +version = "0.6.1" +requires-python = ">=3.8" +description = "Tools for creating and manipulating shapes." +readme = "README.rst" +license = { file = "LICENSE" } +authors = [ + {name = "Vyas Ramasubramani", email = "vramasub@umich.edu"}, + {name = "Bradley Dice", email = "bdice@umich.edu"}, + {name = "Jen Bradley", email = "jenbrad@umich.edu"}, +] +dependencies = ["numpy>=1.19.0","rowan>=1.2.0","scipy>1.0.0"] +keywords = ["geometry"] +dynamic = ["optional-dependencies"] + +[tool.setuptools] +# Build the contents of coxeter rather than the JOSS paper +packages=["coxeter"] + +[tool.setuptools.dynamic] +optional-dependencies = {tests = { file = ["tests/requirements.txt"] }, doc = { file = ["doc/requirements.txt"] }} + +[tool.pytest.ini_options] +# Additional command line options for pytest +addopts = "--doctest-modules -p coxeter.__doctest_fixtures" +doctest_optionflags = "NORMALIZE_WHITESPACE ELLIPSIS" +# Add percentage progress bar to the pytest console output +console_output_style = "progress" +# Specify the tests folder to speed up collection. +testpaths = ["tests"] + +[tool.isort] +skip_glob = "*/extern/*" +multi_line_output = 3 +include_trailing_comma = true +force_grid_wrap = 0 +use_parentheses = true +line_length = 88 +known_third_party = ["hypothesis","pytest"] +known_first_party = ["conftest","coxeter","utils"] + [tool.black] exclude = ''' ( @@ -6,3 +52,12 @@ exclude = ''' )/ ) ''' + +[tool.pydocstyle] +add-ignore =[ + "D105", # Magic methods don't require documentation. + "D107", # __init__ should be documented in class constructors. + "D401", # This doesn't play nice with property docstrings of the form `type: ...` + "D402", # This doesn't play nice with property docstrings of the form `type: ...` + "D403" # This doesn't play nice with property docstrings of the form `type: ...` +] diff --git a/setup.cfg b/setup.cfg index 7040415e..2bb6f07f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,18 +1,3 @@ -[bumpversion] -current_version = 0.6.1 -commit = True -tag = True -message = Bump up to version {new_version}. - -[bdist_wheel] -python-tag = py3 - -[bumpversion:file:coxeter/__init__.py] - -[bumpversion:file:doc/source/conf.py] - -[bumpversion:file:setup.py] - [flake8] # For compatibility with black. max-line-length = 88 @@ -25,25 +10,3 @@ ignore = W503 rst-roles = attr,class,func,meth,mod,obj,ref,term,cite - -[isort] -skip_glob = */extern/* -multi_line_output = 3 -include_trailing_comma = True -force_grid_wrap = 0 -use_parentheses = True -line_length = 88 -known_third_party = hypothesis,pytest -known_first_party = conftest,coxeter,utils - -[pydocstyle] -add-ignore = - D105, # Magic methods don't require documentation. - D107, # __init__ should be documented in class constructors. - D401, # This doesn't play nice with property docstrings of the form `type: ...` - D402, # This doesn't play nice with property docstrings of the form `type: ...` - D403 # This doesn't play nice with property docstrings of the form `type: ...` - -[tool:pytest] -addopts = --doctest-modules -p coxeter.__doctest_fixtures -doctest_optionflags = NORMALIZE_WHITESPACE ELLIPSIS diff --git a/setup.py b/setup.py index 22a45faa..60684932 100644 --- a/setup.py +++ b/setup.py @@ -1,58 +1,3 @@ -import glob -import os +from setuptools import setup -from setuptools import find_packages, setup - -# Read README for PyPI, fallback if it fails. -desc = "Tools for creating and manipulating shapes." -try: - readme_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "README.rst") - with open(readme_file) as f: - readme = f.read() -except ImportError: - readme = desc - -version = "0.6.1" - - -################################################ -# Set up for the various optional dependencies -# that may be installed for additional features. -################################################ - -test_deps = [ - "hypothesis[numpy]", - "matplotlib", - "plato-draw", - "pytest", - "pytest-cov", -] - -bounding_deps = [ - "miniball", -] - -extras = { - "test": test_deps + bounding_deps, - "bounding_sphere": bounding_deps, -} - -# Acquire package data files. -DATA = [fn.replace("coxeter/", "") for fn in glob.glob("coxeter/families/data/*.json")] - -setup( - name="coxeter", - version=version, - description=desc, - long_description=readme, - long_description_content_type="text/x-rst", - url="https://github.com/glotzerlab/coxeter", - author="Vyas Ramasubramani", - author_email="vramasub@umich.edu", - packages=find_packages(), - package_data={"coxeter": DATA}, - install_requires=["numpy>=1.19.0", "rowan>=1.2.0", "scipy>=1.0.0"], - tests_require=test_deps, - extras_require=extras, - zip_safe=False, -) +setup() diff --git a/tests/requirements.txt b/tests/requirements.txt new file mode 100644 index 00000000..af7cde8b --- /dev/null +++ b/tests/requirements.txt @@ -0,0 +1,6 @@ +pytest +pytest-cov +hypothesis[numpy] +matplotlib +miniball +plato-draw