diff --git a/.gitignore b/.gitignore
index 67a380a..1ef7895 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,7 +20,6 @@ Icon*
/docs/apidocs/
/site/
/*.html
-/*.rst
/docs/*.png
# Google Drive
diff --git a/.verchew.ini b/.verchew.ini
index eee3c76..7c02b62 100644
--- a/.verchew.ini
+++ b/.verchew.ini
@@ -11,14 +11,7 @@ versions = Python 3.4. | Python 3.5. | Python 3.6
[pipenv]
cli = pipenv
-versions = 10.1.1 | 10.1.2
-
-[pandoc]
-
-cli = pandoc
-version = 1.
-optional = true
-message = This is only needed to generate the README for PyPI.
+versions = 10. | 11.
[Graphviz]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eff69b2..e7e7125 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Revision History
+## 0.4 (2018/4/28)
+
+- Added `reset=True` as `init()` option to replace all existing logging handlers.
+- Added `exception` logging API.
+- Added convenience alias: `log.c`, `log.exc`.
+
## 0.3.1 (2018/03/30)
- Fixed bug where records were written for disabled levels.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 19feb0d..629986a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -9,7 +9,6 @@
* Mac: http://developer.apple.com/xcode
* Linux: http://www.gnu.org/software/make
* pipenv: http://docs.pipenv.org
-* Pandoc: http://johnmacfarlane.net/pandoc/installing.html
* Graphviz: http://www.graphviz.org/Download.php
To confirm these system dependencies are configured correctly:
diff --git a/Makefile b/Makefile
index f0d1f51..fa1db3b 100644
--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,7 @@ DEPENDENCIES := $(VENV)/.pipenv-$(shell bin/checksum Pipfile* setup.py)
install: $(DEPENDENCIES)
$(DEPENDENCIES):
+ pipenv run python setup.py develop
pipenv install --dev
@ touch $@
@@ -161,15 +162,12 @@ build: dist
.PHONY: dist
dist: install $(DIST_FILES)
-$(DIST_FILES): $(MODULES) README.rst CHANGELOG.rst
+$(DIST_FILES): $(MODULES)
rm -f $(DIST_FILES)
- pipenv run python setup.py check --restructuredtext --strict --metadata
+ pipenv run python setup.py check --strict --metadata
pipenv run python setup.py sdist
pipenv run python setup.py bdist_wheel
-%.rst: %.md
- pandoc -f markdown_github -t rst -o $@ $<
-
.PHONY: exe
exe: install $(EXE_FILES)
$(EXE_FILES): $(MODULES) $(PROJECT).spec
@@ -187,7 +185,7 @@ TWINE := pipenv run twine
upload: dist ## Upload the current version to PyPI
git diff --name-only --exit-code
$(TWINE) upload dist/*.*
- bin/open https://pypi.python.org/pypi/$(PROJECT)
+ bin/open https://pypi.org/project/$(PROJECT)
# CLEANUP #####################################################################
diff --git a/Pipfile b/Pipfile
index ddd2646..7f0db3b 100644
--- a/Pipfile
+++ b/Pipfile
@@ -1,6 +1,6 @@
[[source]]
-url = "https://pypi.python.org/simple"
+url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
@@ -8,19 +8,14 @@ name = "pypi"
python_version = "3"
-[packages]
-
-minilog = { path = ".", editable = true }
-
[dev-packages]
# Linters
-pylint = "~=1.7.5"
-astroid = "~=1.5.3" # temporary to work around apparent regression in 1.6
+pylint = "*"
pycodestyle = "*"
pydocstyle = "*"
-# # Testing
+# Testing
pytest = "~= 3.3"
pytest-describe = "*"
pytest-expecter = "*"
@@ -28,8 +23,8 @@ pytest-random = "*"
pytest-ordering = "*"
pytest-cov = "*"
-# # Reports
-"coverage.space" = "*"
+# Reports
+coverage-space = "*"
# Documentation
mkdocs = "*"
@@ -41,9 +36,10 @@ wheel = "*"
pyinstaller = "*"
# Release
-twine = "*"
+setuptools = ">= 38.6.0"
+twine = ">= 1.11.0"
# Tooling
sniffer = "*"
-pync = {version = "< 2.0", sys_platform = "== 'darwin'"}
-MacFSEvents = {version = "*", sys_platform = "== 'darwin'"}
+pync = { version = "<2.0", sys_platform = "== 'darwin'" }
+MacFSEvents = { version = "*", sys_platform = "== 'darwin'" }
diff --git a/Pipfile.lock b/Pipfile.lock
index a633362..244d879 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
- "sha256": "7ccd9267ff8075bd8803928257e72fb4db48c5566192171231a2a0f8765115fc"
+ "sha256": "3749edaf5935b5f0691d9290f45aee6bb2e9df2d3200e412c152b2365b9f8f64"
},
"pipfile-spec": 6,
"requires": {
@@ -10,17 +10,12 @@
"sources": [
{
"name": "pypi",
- "url": "https://pypi.python.org/simple",
+ "url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
- "default": {
- "minilog": {
- "editable": true,
- "path": "."
- }
- },
+ "default": {},
"develop": {
"altgraph": {
"hashes": [
@@ -31,10 +26,10 @@
},
"astroid": {
"hashes": [
- "sha256:39a21dd2b5d81a6731dc0ac2884fa419532dffd465cdd43ea6c168d36b76efb3",
- "sha256:492c2a2044adbf6a84a671b7522e9295ad2f6a7c781b899014308db25312dd35"
+ "sha256:35cfae47aac19c7b407b7095410e895e836f2285ccf1220336afba744cc4c5f2",
+ "sha256:38186e481b65877fd8b1f9acc33e922109e983eb7b6e487bd4c71002134ad331"
],
- "version": "==1.5.3"
+ "version": "==1.6.3"
},
"attrs": {
"hashes": [
@@ -52,10 +47,10 @@
},
"certifi": {
"hashes": [
- "sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296",
- "sha256:edbc3f203427eef571f79a7692bb160a2b0f7ccaa31953e99bd17e307cf63f7d"
+ "sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7",
+ "sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0"
],
- "version": "==2018.1.18"
+ "version": "==2018.4.16"
},
"chardet": {
"hashes": [
@@ -119,12 +114,13 @@
],
"version": "==4.5.1"
},
- "coverage.space": {
+ "coverage-space": {
"hashes": [
- "sha256:31cb5ba7d28d389e29e9779ba204de27c333d8589161cebe03a1cb1503c66059",
- "sha256:54f0e5bf3cfec621b5625969351207f937668bea9159a4c635f722c997bfe546"
+ "sha256:e68f7451acee5b23f1ec374739e6011321712db319eee9b8e264d5d28911f701",
+ "sha256:e89e898bdbb4aa45ccb57124a5136e4c03a73711919e8e23b6110400c61017cd"
],
- "version": "==0.8"
+ "index": "pypi",
+ "version": "==1.0"
},
"docopt": {
"hashes": [
@@ -138,16 +134,9 @@
"sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
"sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
],
+ "index": "pypi",
"version": "==0.14"
},
- "funcsigs": {
- "hashes": [
- "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca",
- "sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"
- ],
- "markers": "python_version < '3.0'",
- "version": "==1.0.2"
- },
"future": {
"hashes": [
"sha256:e39ced1ab767b5936646cedba8bcce582398233d6a627067d4c6a454c90cfedb"
@@ -221,6 +210,7 @@
"hashes": [
"sha256:1324b66b356051de662ba87d84f73ada062acd42b047ed1246e60a449f833e10"
],
+ "index": "pypi",
"markers": "sys_platform == 'darwin'",
"version": "==0.8.1"
},
@@ -253,10 +243,19 @@
},
"mkdocs": {
"hashes": [
- "sha256:150795179c32bde225a3596c57b677f856f544351e809048f654cab3fbac90bd",
- "sha256:4a6b6b062347448ed42d5e8c0dce8f912e647ce4bd480fdea25017cd63aaa3a1"
+ "sha256:126e9b871adeb077facccc375066fddae1485c7deebe3f10f2052b9a15514fb9",
+ "sha256:5f4317fd593ea07798bdb083bc06ca4e6b1e745fd1240d459f03cd0af1d58692"
+ ],
+ "index": "pypi",
+ "version": "==0.17.3"
+ },
+ "more-itertools": {
+ "hashes": [
+ "sha256:0dd8f72eeab0d2c3bd489025bb2f6a1b8342f9b198f6fc37b52d15cfa4531fea",
+ "sha256:11a625025954c20145b37ff6309cd54e39ca94f72f6bb9576d1195db6fa2442e",
+ "sha256:c9ce7eccdcb901a2c75d326ea134e0886abfbea5f93e91cc95de9507c0816c44"
],
- "version": "==0.17.2"
+ "version": "==4.1.0"
},
"nose": {
"hashes": [
@@ -274,30 +273,34 @@
},
"pkginfo": {
"hashes": [
- "sha256:31a49103180ae1518b65d3f4ce09c784e2bc54e338197668b4fb7dc539521024",
- "sha256:bb1a6aeabfc898f5df124e7e00303a5b3ec9a489535f346bfbddb081af93f89e"
+ "sha256:5878d542a4b3f237e359926384f1dde4e099c9f5525d236b1840cf704fa8d474",
+ "sha256:a39076cb3eb34c333a0dd390b568e9e1e881c7bf2cc0aee12120636816f55aee"
],
- "version": "==1.4.1"
+ "version": "==1.4.2"
},
"pluggy": {
"hashes": [
- "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff"
+ "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff",
+ "sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c",
+ "sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5"
],
"version": "==0.6.0"
},
"py": {
"hashes": [
- "sha256:8cca5c229d225f8c1e3085be4fcf306090b00850fefad892f9d96c7b6e2f310f",
- "sha256:ca18943e28235417756316bfada6cd96b23ce60dd532642690dcfdaba988a76d"
+ "sha256:29c9fab495d7528e80ba1e343b958684f4ace687327e6f789a94bf3d1915f881",
+ "sha256:983f77f3331356039fdd792e9220b7b8ee1aa6bd2b25f567a963ff1de5a64f6a"
],
- "version": "==1.5.2"
+ "version": "==1.5.3"
},
"pycodestyle": {
"hashes": [
- "sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766",
- "sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9"
+ "sha256:74abc4e221d393ea5ce1f129ea6903209940c1ecd29e002e8c6933c2b21026e0",
+ "sha256:cbc619d09254895b0d12c2c691e237b2e91e9b2ecf5e84c26b35400f93dcfb83",
+ "sha256:cbfca99bd594a10f674d0cd97a3d802a1fdef635d4361e1a2658de47ed261e3a"
],
- "version": "==2.3.1"
+ "index": "pypi",
+ "version": "==2.4.0"
},
"pydocstyle": {
"hashes": [
@@ -305,6 +308,7 @@
"sha256:4d5bcde961107873bae621f3d580c3e35a426d3687ffc6f8fb356f6628da5a97",
"sha256:af9fcccb303899b83bec82dc9a1d56c60fc369973223a5e80c3dfa9bdf984405"
],
+ "index": "pypi",
"version": "==2.1.1"
},
"pygments": {
@@ -312,54 +316,62 @@
"sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
"sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
],
+ "index": "pypi",
"version": "==2.2.0"
},
"pyinstaller": {
"hashes": [
"sha256:715f81f24b1ef0e5fe3b3c71e7540551838e46e9de30882aa7c0a521147fd1ce"
],
+ "index": "pypi",
"version": "==3.3.1"
},
"pylint": {
"hashes": [
- "sha256:b4d4d368f1d3834807d9d98f6ebe2af52c8e71c7c641a5a4cf87f479701c884a",
- "sha256:f3287a9ee5427b013df37cfddd5e9e89df5b03dacb2e2ea448e7b78dd27b674b"
+ "sha256:0b7e6b5d9f1d4e0b554b5d948f14ed7969e8cdf9a0120853e6e5af60813b18ab",
+ "sha256:34738a82ab33cbd3bb6cd4cef823dbcabdd2b6b48a4e3a3054a2bbbf0c712be9"
],
- "version": "==1.7.6"
+ "index": "pypi",
+ "version": "==1.8.4"
},
"pync": {
"hashes": [
"sha256:85737aab9fc69cf59dc9fe831adbe94ac224944c05e297c98de3c2413f253530"
],
+ "index": "pypi",
"markers": "sys_platform == 'darwin'",
"version": "==1.6.1"
},
"pytest": {
"hashes": [
- "sha256:062027955bccbc04d2fcd5d79690947e018ba31abe4c90b2c6721abec734261b",
- "sha256:117bad36c1a787e1a8a659df35de53ba05f9f3398fb9e4ac17e80ad5903eb8c5"
+ "sha256:54713b26c97538db6ff0703a12b19aeaeb60b5e599de542e7fca0ec83b9038e8",
+ "sha256:829230122facf05a5f81a6d4dfe6454a04978ea3746853b2b84567ecf8e5c526"
],
- "version": "==3.4.2"
+ "index": "pypi",
+ "version": "==3.5.1"
},
"pytest-cov": {
"hashes": [
"sha256:03aa752cf11db41d281ea1d807d954c4eda35cfa1b21d6971966cc041bbf6e2d",
"sha256:890fe5565400902b0c78b5357004aab1c814115894f4f21370e2433256a3eeec"
],
+ "index": "pypi",
"version": "==2.5.1"
},
"pytest-describe": {
"hashes": [
"sha256:bd6be131452b7822c872735ffe53ce3931b3b80cbbad1647c2b482cc9ef3d00e"
],
+ "index": "pypi",
"version": "==0.11.1"
},
"pytest-expecter": {
"hashes": [
- "sha256:4472ea85240c5394c427a1ca1cedd6c7427d02b589845360744f04420cd21e94",
- "sha256:aa455bbb79c10eac0864fc37fb28de2932e3af61da122e2732a0634fa0d8077c"
+ "sha256:9d579961379026f5c2211070125f042f882fc0db00488b10ebbdf79491679ff6",
+ "sha256:efd92985547f2f2b170d8b7459d00075d9694d3ebdabfb41dbb7f71d9183d5e0"
],
- "version": "==1.1"
+ "index": "pypi",
+ "version": "==1.2"
},
"pytest-ordering": {
"hashes": [
@@ -367,20 +379,22 @@
"sha256:6aae68bf7fad5411ec9b0f6d3ead33a781c71d333d5150e75990cd54ae4d840e",
"sha256:98ae00eaa1f4c25570327952016f17a0c4dcb2717d9c98766d071aefe629e2ff"
],
+ "index": "pypi",
"version": "==0.5"
},
"pytest-random": {
"hashes": [
"sha256:92f25db8c5d9ffc20d90b51997b914372d6955cb9cf1f6ead45b90514fc0eddd"
],
+ "index": "pypi",
"version": "==0.2"
},
"python-dateutil": {
"hashes": [
- "sha256:891c38b2a02f5bb1be3e4793866c8df49c7d19baabf9c1bad62547e0b4866aca",
- "sha256:95511bae634d69bc7329ba55e646499a842bc4ec342ad54a8cdb65645a0aad3c"
+ "sha256:3220490fb9741e2342e1cf29a503394fdac874bc39568288717ee67047ff29df",
+ "sha256:9d8074be4c993fbe4947878ce593052f71dac82932a677d49194d8ce9778002e"
],
- "version": "==2.6.1"
+ "version": "==2.7.2"
},
"python-termstyle": {
"hashes": [
@@ -434,6 +448,7 @@
"sha256:e8a0daa4c51dff3d00482b45dc9b978159100a8d5a7df327c28ed96586559970",
"sha256:e90c1ad4bd3c31a5fad8e03d45dfc83377b31420aa0779f17280c817ce0c9dd8"
],
+ "index": "pypi",
"version": "==0.4.0"
},
"snowballstemmer": {
@@ -445,27 +460,28 @@
},
"tornado": {
"hashes": [
- "sha256:4b6a623a28307c5d5d64b34ed7c84f2bfcc6848fd71546bb8bc03dd82b71ad04",
- "sha256:54a568429fb77529622a4607c66f9144aa980bd4fe2326206672707eba6951fc",
- "sha256:62f754562c61ea94b00d61727202105068bc2760f076cc34d2da1a57041731aa",
- "sha256:6b56415667b1ad4f222486baa7118d5445310fd9b99a2263e029bc63df6e2e80",
- "sha256:f112ae0b50d2080995afab36aca4fcd93af1fa2e7185b15d854b0d6b2578dce4"
+ "sha256:5ef073ac6180038ccf99411fe05ae9aafb675952a2c8db60592d5daf8401f803",
+ "sha256:6d14e47eab0e15799cf3cdcc86b0b98279da68522caace2bd7ce644287685f0a",
+ "sha256:92b7ca81e18ba9ec3031a7ee73d4577ac21d41a0c9b775a9182f43301c3b5f8e",
+ "sha256:ab587996fe6fb9ce65abfda440f9b61e4f9f2cf921967723540679176915e4c3",
+ "sha256:b36298e9f63f18cad97378db2222c0e0ca6a55f6304e605515e05a25483ed51a"
],
- "version": "==5.0"
+ "version": "==4.5.3"
},
"tqdm": {
"hashes": [
- "sha256:5ec0d4442358e55cdb4a0471d04c6c831518fd8837f259db5537d90feab380df",
- "sha256:f66468c14ccd011a627734c9b3fd72f20ce16f8faecc47384eb2507af5924fb9"
+ "sha256:22c760d05b2eb6e96a91ad7ed1b03c9c97e6256fb7716410c27c2cb3265a5913",
+ "sha256:d7bfa112a55290a5e2d0c3263a09b17b24240686fbf20d1ef7c5e8edfbb71ad0"
],
- "version": "==4.19.6"
+ "version": "==4.23.1"
},
"twine": {
"hashes": [
- "sha256:caa45b7987fc96321258cd7668e3be2ff34064f5c66d2d975b641adca659c1ab",
- "sha256:d3ce5c480c22ccfb761cd358526e862b32546d2fe4bc93d46b5cf04ea3cc46ca"
+ "sha256:08eb132bbaec40c6d25b358f546ec1dc96ebd2638a86eea68769d9e67fe2b129",
+ "sha256:2fd9a4d9ff0bcacf41fdc40c8cb0cfaef1f1859457c9653fd1b92237cc4e9f25"
],
- "version": "==1.9.1"
+ "index": "pypi",
+ "version": "==1.11.0"
},
"urllib3": {
"hashes": [
@@ -476,10 +492,11 @@
},
"wheel": {
"hashes": [
- "sha256:9515fe0a94e823fd90b08d22de45d7bde57c90edce705b22f5e1ecf7e1b653c8",
- "sha256:e721e53864f084f956f40f96124a74da0631ac13fbbd1ba99e8e2b5e9cafdf64"
+ "sha256:1ae8153bed701cb062913b72429bcf854ba824f973735427681882a688cb55ce",
+ "sha256:9cdc8ab2cc9c3c2e2727a4b67c22881dbb0e1c503d592992594c5e131c867107"
],
- "version": "==0.30.0"
+ "index": "pypi",
+ "version": "==0.31.0"
},
"wrapt": {
"hashes": [
diff --git a/README.md b/README.md
index 6b74c8a..4584941 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
-Unix: [![Unix Build Status](https://img.shields.io/travis/jacebrowning/minilog/develop.svg)](https://travis-ci.org/jacebrowning/minilog) Windows: [![Windows Build Status](https://img.shields.io/appveyor/ci/jacebrowning/minilog/develop.svg)](https://ci.appveyor.com/project/jacebrowning/minilog)
Metrics: [![Coverage Status](https://img.shields.io/coveralls/jacebrowning/minilog/develop.svg)](https://coveralls.io/r/jacebrowning/minilog) [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/jacebrowning/minilog.svg)](https://scrutinizer-ci.com/g/jacebrowning/minilog/?branch=develop)
Usage: [![PyPI Version](https://img.shields.io/pypi/v/minilog.svg)](https://pypi.python.org/pypi/minilog)
+Unix: [![Unix Build Status](https://img.shields.io/travis/jacebrowning/minilog/develop.svg)](https://travis-ci.org/jacebrowning/minilog) Windows: [![Windows Build Status](https://img.shields.io/appveyor/ci/jacebrowning/minilog/develop.svg)](https://ci.appveyor.com/project/jacebrowning/minilog)
Metrics: [![Coverage Status](https://img.shields.io/coveralls/jacebrowning/minilog/develop.svg)](https://coveralls.io/r/jacebrowning/minilog) [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/jacebrowning/minilog.svg)](https://scrutinizer-ci.com/g/jacebrowning/minilog/?branch=develop)
Usage: [![PyPI Version](https://img.shields.io/pypi/v/minilog.svg)](https://pypi.org/project/minilog)
# Overview
-Every project should utilize logging, but sometimes the required boilerplate is too much. Instead of including this:
+Every project should utilize logging, but for simple use cases, this requires a bit too much boilerplate. Instead of including all of this in your modules:
```python
import logging
diff --git a/docs/api.md b/docs/api.md
index 592e3a0..c3c4eab 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -1,6 +1,6 @@
# Logging
-This package intends to be a drop-in replacement for `logging.Logger` objects. It supports standard the logging API:
+This package intends to be a drop-in replacement for `logging.Logger` objects. It supports the standard logging API:
```python
log.debug(message, *args)
@@ -29,8 +29,20 @@ Set the format for all logging handlers:
```python
log.init(format="%(levelname)s: %(name)s: %(message)s")
-log.init(format="%(levelname)s: %(name)s: %(message)s", debug=True)
-log.init(format="%(levelname)s: %(name)s: %(message)s", level=log.WARNING)
+
+```
+
+Set the level for the root logging handler:
+
+```python
+log.init(format=<…>, debug=True)
+log.init(format=<…>, level=log.WARNING)
+```
+
+Replace all existing loggers before initialization:
+
+```python
+log.init(reset=True, format=<…>, level=<…>)
```
Set the logging level for specific named loggers:
diff --git a/log/__init__.py b/log/__init__.py
index 3b7796a..ddd47ba 100644
--- a/log/__init__.py
+++ b/log/__init__.py
@@ -9,6 +9,8 @@
i = info
w = warn = warning
e = error
+c = critical
+exc = exception
__project__ = 'minilog'
-__version__ = '0.3.1'
+__version__ = '0.4'
diff --git a/log/helpers.py b/log/helpers.py
index 365d7c7..c59f0b4 100644
--- a/log/helpers.py
+++ b/log/helpers.py
@@ -9,7 +9,11 @@
initialized = False
-def init(debug=False, **kwargs):
+def init(*, reset=False, debug=False, **kwargs):
+ if reset:
+ for handler in logging.root.handlers[:]:
+ logging.root.removeHandler(handler)
+
custom_format = kwargs.get('format')
default_level = logging.DEBUG if debug else DEFAULT_LEVEL
diff --git a/log/logger.py b/log/logger.py
index dd3e937..ce1aefa 100644
--- a/log/logger.py
+++ b/log/logger.py
@@ -1,5 +1,6 @@
"""Replicates some of the `logging.Logger` API."""
+import sys
import logging
from . import utils
@@ -29,5 +30,6 @@ def critical(message, *args, **kwargs):
log(logging.CRITICAL, message, *args, **kwargs)
-def exception(*args, **kwargs): # pylint: disable=unused-argument
- raise NotImplementedError
+def exception(message, *args, **kwargs):
+ kwargs['exc_info'] = kwargs.get('exc_info', sys.exc_info())
+ log(logging.ERROR, message, *args, **kwargs)
diff --git a/log/tests/test_api.py b/log/tests/test_api.py
index 8583fa1..b31cb85 100644
--- a/log/tests/test_api.py
+++ b/log/tests/test_api.py
@@ -5,13 +5,15 @@
import log
-@pytest.mark.parametrize("name, levelname", [
+@pytest.mark.parametrize('name, levelname', [
+ ('c', 'CRITICAL'),
('critical', 'CRITICAL'),
('d', 'DEBUG'),
('debug', 'DEBUG'),
('e', 'ERROR'),
('error', 'ERROR'),
- # ('exception', 'ERROR'),
+ ('exc', 'ERROR'),
+ ('exception', 'ERROR'),
('i', 'INFO'),
('info', 'INFO'),
('w', 'WARNING'),
diff --git a/log/utils.py b/log/utils.py
index 7b65341..f72ca86 100644
--- a/log/utils.py
+++ b/log/utils.py
@@ -6,7 +6,7 @@
from . import helpers
-def create_logger_record(level, message, *args, **kwargs):
+def create_logger_record(level, message, *args, exc_info=None, **kwargs):
if not helpers.initialized:
helpers.init()
@@ -24,7 +24,7 @@ def create_logger_record(level, message, *args, **kwargs):
lno=lineno,
msg=message,
args=args,
- exc_info=None,
+ exc_info=exc_info,
extra=kwargs,
sinfo=None,
)
diff --git a/setup.py b/setup.py
index bc04986..4e0533c 100644
--- a/setup.py
+++ b/setup.py
@@ -24,13 +24,9 @@ def read_package_variable(key, filename='__init__.py'):
def build_description():
"""Build a description for the project from documentation files."""
- try:
- readme = open("README.rst").read()
- changelog = open("CHANGELOG.rst").read()
- except IOError:
- return ""
- else:
- return readme + '\n' + changelog
+ readme = open("README.md").read()
+ changelog = open("CHANGELOG.md").read()
+ return readme + '\n' + changelog
setuptools.setup(
@@ -45,6 +41,7 @@ def build_description():
packages=setuptools.find_packages(),
long_description=build_description(),
+ long_description_content_type='text/markdown',
license='MIT',
classifiers=[
'Development Status :: 4 - Beta',
diff --git a/tests/test_records.py b/tests/test_records.py
index 476a1ae..e1a9800 100644
--- a/tests/test_records.py
+++ b/tests/test_records.py
@@ -20,6 +20,15 @@ def it_can_be_formatted_with_init(expect, caplog):
demo.greet("format")
expect(caplog.text) == "ERROR: tests.demo: Hello, format!\n"
+ def it_can_include_exceptions(expect, caplog):
+ try:
+ print(1 / 0)
+ except ZeroDivisionError:
+ log.exception("exception")
+ expect(caplog.text).contains('Traceback ')
+ expect(caplog.text).contains('test_records.py", line 25, ')
+ expect(caplog.text).contains('ZeroDivisionError')
+
def describe_silence():