Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 9 additions & 27 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,43 +19,25 @@ Create your own fork of this repo that you will make your changes on.

## Creating your feature

Always base your changes off the `main` branch, it is the most up to date.
Always base your changes off the `main` branch unless otherwise asked.

## Pull Request

Once the feature is tested and ready, open a pull request to the `main` branch.
All pull requests must:

Please ensure your tests are passing in your local environment and any new
features are have appropriate tests added. Untested code will not be approved.
- Pass all linting and formatting checks
- Have tests that cover all branches of the added feature
- If the PR is a bug fix there must be a test that duplicates the bug, proving
it is fixed

## Code Style

Follow the patterns seen in the code. Walk where others have walked.

The majority of code style nits will be met simply by passing `pre-commit`
checks prior to submitting a pull request.
The majority of code style nits will be met when passing `pre-commit` checks
prior to submitting a pull request.

- ### Do

- snake_case modules, variables, methods, and functions
- PascalCase classes
- Type-hint function/method signatures
- Use verbs for getters/setters (`get_`, `fetch_`, `pull_`, `save_`, `put_`)
- Use singular form for objects
- Use plural form for lists/sequences

- ### Do Not

- Fight `black` formatting

- ### Comments

- Keep comments short and to the point
- Let code explain "what" and comments explain "why"
- All modules, functions, class, and methods must have a doc-string
- Doc-strings are optional in tests when the test name explains "what"

- ### Tests
## Tests

- Smaller tests are easier to work with
- Mock at a minimum
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ COPY requirements/ /src/requirements/
RUN python3.8 -m pip install --upgrade -r requirements/requirements-dev.txt -r requirements/requirements-test.txt --no-cache-dir

COPY . /src
RUN python3.8 -m pip install .
RUN python3.8 -m pip install . --no-cache-dir

CMD ["tox", "-r"]
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Preocts
Copyright (c) 2023 Preocts

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
18 changes: 2 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.PHONY: install
install:
python -m pip install --upgrade .

.PHONY: install-dev
install-dev:
python -m pip install --upgrade --editable .[dev,test]
Expand All @@ -18,21 +14,11 @@ upgrade-dev:
coverage:
coverage run -m pytest tests/
coverage report -m
coverage html
@# This should work for most linux and windows users
@# python -c "import os;import webbrowser; webbrowser.open(f'{os.getcwd()}/htmlcov/index.html')"

@# WSL users can use this (change Ubuntu-20.04 to your distro name)
python -c "import os;import webbrowser; webbrowser.open(f'file://wsl.localhost/Ubuntu-20.04{os.getcwd()}/htmlcov/index.html')"

.PHONY: docker-test
docker-test:
docker build -t docker-test .
docker run --rm docker-test

.PHONY: docker-clean
docker-clean:
docker system prune -f
docker build -t pydocker-test .
docker run --rm pydocker-test

.PHONY: build-dist
build-dist:
Expand Down
43 changes: 26 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@

# python-src-template

## Playing around with a new structure. See the releases for previous structures.
A template I use for most projects and is setup to jive with my environment at the company I work with.

## A template I use for most projects.
This is not the one-shot solution to project structure or packaging. This is
just what works well for one egg on the Internet. Feel free to use it as you see
fit.

Straight forward to use!

**Kind of...**
The primary setup here uses dynamically loaded requirement files from the
`./requirements` directory in the pyproject.toml file. This is ideal for
micro-services, applications, or scripts that need all requirements pinned.
Pinning is handled by `pip-compile`. The files in `./alt_files` offer an
alternative where all requirements are kept within the pyproject.toml file and
any pinning is manually managed.

---

Expand Down Expand Up @@ -90,10 +95,16 @@ Run pre-commit on all files:
$ pre-commit run --all-files
```

Run tests:
Run tests (quick):

```console
$ pytest
```

Run tests (slow):

```console
$ tox [-r] [-e py3x]
$ tox
```

Build dist:
Expand Down Expand Up @@ -143,13 +154,11 @@ This repo has a Makefile with some quality of life scripts if the system
supports `make`. Please note there are no checks for an active `venv` in the
Makefile.

| PHONY | Description |
| -------------- | ------------------------------------------------------------------------------------------ |
| `install` | install the project |
| `install-dev` | install development/test requirements and project as editable install |
| `upgrade-dev` | update all dependencies, regenerate requirements.txt (disabled by default) |
| `coverage` | Run tests with coverage, generate html report, and open browser (double check based on os) |
| `docker-test' | Run coverage and tests in a docker container. |
| `docker-clean` | Run `docker system prune -f` |
| `build-dist` | Build source distribution and wheel distribution |
| `clean` | Deletes build, tox, coverage, pytest, mypy, cache, and pyc artifacts |
| PHONY | Description |
| ------------- | --------------------------------------------------------------------- |
| `install-dev` | install development/test requirements and project as editable install |
| `upgrade-dev` | update all dependencies, regenerate requirements.txt |
| `coverage` | Run tests with coverage, generate console report |
| `docker-test' | Run coverage and tests in a docker container. |
| `build-dist` | Build source distribution and wheel distribution |
| `clean` | Deletes build, tox, coverage, pytest, mypy, cache, and pyc artifacts |
17 changes: 17 additions & 0 deletions alt_files/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM ubuntu:focal

RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends software-properties-common
RUN add-apt-repository -y 'ppa:deadsnakes/ppa'
RUN DEBIAN_FRONTEND=noninteractive apt install -y --no-install-recommends python3.8 python3.8-venv
RUN rm -rf /var/lib/apt/lists/*

WORKDIR /src

ENV PATH=/venv/bin:$PATH
RUN python3.8 -m venv /venv

COPY . /src
RUN python3.8 -m pip install . --no-cache-dir

CMD ["tox", "-r"]
35 changes: 35 additions & 0 deletions alt_files/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.PHONY: install-dev
install-dev:
python -m pip install --upgrade --editable .[dev,test]
pre-commit install

.PHONY: coverage
coverage:
coverage run -m pytest tests/
coverage report -m

.PHONY: docker-test
docker-test:
docker build -t pydocker-test .
docker run --rm pydocker-test

.PHONY: build-dist
build-dist:
python -m pip install --upgrade build
python -m build

.PHONY: clean
clean:
find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} +
find . -name '__pycache__' -exec rm -rf {} +
find . -name '.mypy_cache' -exec rm -rf {} +
rm -rf .tox
rm -f coverage.xml
rm -f coverage.json
rm -rf htmlcov
rm -rf .coverage
rm -rf .coverage.*
find . -name '.pytest_cache' -exec rm -rf {} +
rm -rf dist
rm -rf build
129 changes: 129 additions & 0 deletions alt_files/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "module-name"
version = "0.1.0"
requires-python = ">=3.7"
description = "Module Description"
readme = "README.md"
license = { file = "LICENSE" }
authors = [
{ email = "yourname@email.invalid", name = "[YOUR NAME]" }
]
maintainers = []
keywords = []
classifiers = [
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: Implementation :: CPython"
]

dependencies = []

[project.optional-dependencies]
dev = [
"pre-commit",
"black",
"mypy",
"flake8",
"flake8-builtins",
"flake8-pep585",
]
test = [
"pytest",
"pytest-randomly",
"coverage",
"tox"
]

[project.urls]
homepage = "https://github.com/[ORG NAME]/[REPO NAME]"
# documentation = ""
# repository = ""
# changelog = ""

# CLI scripts if needed
# [project.scripts]
# python-src-example = "module_name.sample:main"

[tool.setuptools.package-data]
"module_name" = ["py.typed"]

[tool.mypy]
check_untyped_defs = true
disallow_any_generics = true
disallow_incomplete_defs = true
disallow_untyped_defs = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true

[[tool.mypy.overrides]]
module = "tests.*"
disallow_incomplete_defs = false
disallow_untyped_defs = false
warn_unused_ignores = false

[tool.coverage.run]
branch = true
source = [
"tests",
]
source_pkgs = [
"module_name",
]

[tool.coverage.paths]
source = [
"src/",
"*/site-packages",
]
test = [
"tests/",
"*/tests",
]

[tool.coverage.report]
exclude_lines =[
"pragma: no cover",
"raise NotImplementedError",
"if __name__ == .__main__.:",
"\\.\\.\\.",
"if TYPE_CHECKING:",
]

# This is ignored by flake8, here in case they decide to add it in the future
[tool.flake8]
ignore = "W503,E203"
max-line-length = 88

[tool.tox]
legacy_tox_ini = """
[tox]
envlist = py37,py38,py39,py310,py311,py312,coverage,mypy
skip_missing_interpreters = true
isolated_build = True

[testenv]
deps =
.[test]
commands =
coverage run -p -m pytest tests/

[testenv:coverage]
depends = py37,py38,py39,py310,py311,py312
parallel_show_output = true
commands =
python -m coverage combine
python -m coverage report -m --fail-under=50
python -m coverage json

[testenv:mypy]
deps =
mypy
commands =
mypy -p module_name --no-incremental
"""