Skip to content

Commit d3faba7

Browse files
v1.1.4 :octocat:
1 parent e1d5cd4 commit d3faba7

File tree

10 files changed

+137
-130
lines changed

10 files changed

+137
-130
lines changed

Diff for: .github/workflows/build.yml

+72-43
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
name: Build
22

33
on:
4+
release:
5+
types: [published]
46
push:
57
branches:
68
- master
79
- ci
810
pull_request:
911
branches:
10-
- '*'
12+
- "*"
1113

1214
env:
1315
PROJECT_NAME: essentials
@@ -17,56 +19,83 @@ jobs:
1719
runs-on: ubuntu-18.04
1820
strategy:
1921
matrix:
20-
python-version: [3.7, 3.8]
22+
python-version: [3.6, 3.7, 3.8, 3.9]
2123

2224
steps:
23-
- uses: actions/checkout@v1
24-
with:
25-
fetch-depth: 9
26-
submodules: false
25+
- uses: actions/checkout@v1
26+
with:
27+
fetch-depth: 9
28+
submodules: false
2729

28-
- name: Use Python ${{ matrix.python-version }}
29-
uses: actions/setup-python@v1
30-
with:
31-
python-version: ${{ matrix.python-version }}
30+
- name: Use Python ${{ matrix.python-version }}
31+
uses: actions/setup-python@v1
32+
with:
33+
python-version: ${{ matrix.python-version }}
3234

33-
- uses: actions/cache@v1
34-
id: depcache
35-
with:
36-
path: deps
37-
key: requirements-pip-${{ matrix.python-version }}-${{ hashFiles('requirements.txt') }}
35+
- uses: actions/cache@v1
36+
id: depcache
37+
with:
38+
path: deps
39+
key: requirements-pip-${{ matrix.python-version }}-${{ hashFiles('requirements.txt') }}
3840

39-
- name: Download dependencies
40-
if: steps.depcache.outputs.cache-hit != 'true'
41-
run: |
42-
pip download --dest=deps -r requirements.txt
41+
- name: Download dependencies
42+
if: steps.depcache.outputs.cache-hit != 'true'
43+
run: |
44+
pip download --dest=deps -r requirements.txt
4345
44-
- name: Install dependencies
45-
run: |
46-
pip install -U --no-index --find-links=deps deps/*
46+
- name: Install dependencies
47+
run: |
48+
pip install -U --no-index --find-links=deps deps/*
4749
48-
- name: Run tests
49-
run: |
50-
flake8 && pytest --doctest-modules --junitxml=junit/pytest-results-${{ matrix.python-version }}.xml --cov=$PROJECT_NAME --cov-report=xml tests/
50+
- name: Run tests
51+
run: |
52+
flake8 && pytest --doctest-modules --junitxml=junit/pytest-results-${{ matrix.python-version }}.xml --cov=$PROJECT_NAME --cov-report=xml tests/
5153
52-
- name: Upload pytest test results
53-
uses: actions/upload-artifact@master
54-
with:
55-
name: pytest-results-${{ matrix.python-version }}
56-
path: junit/pytest-results-${{ matrix.python-version }}.xml
57-
if: always()
54+
- name: Upload pytest test results
55+
uses: actions/upload-artifact@master
56+
with:
57+
name: pytest-results-${{ matrix.python-version }}
58+
path: junit/pytest-results-${{ matrix.python-version }}.xml
59+
if: always()
5860

59-
- name: Install distribution dependencies
60-
run: pip install --upgrade twine setuptools wheel
61-
if: matrix.python-version == 3.8
61+
- name: Codecov
62+
run: |
63+
bash <(curl -s https://codecov.io/bash)
6264
63-
- name: Create distribution package
64-
run: python setup.py sdist bdist_wheel
65-
if: matrix.python-version == 3.8
65+
- name: Install distribution dependencies
66+
run: pip install --upgrade twine setuptools wheel
67+
if: matrix.python-version == 3.8 || matrix.python-version == 3.9
6668

67-
- name: Upload distribution package
68-
uses: actions/upload-artifact@master
69-
with:
70-
name: dist-package-${{ matrix.python-version }}
71-
path: dist
72-
if: matrix.python-version == 3.8
69+
- name: Create distribution package
70+
run: python setup.py sdist bdist_wheel
71+
if: matrix.python-version == 3.8 || matrix.python-version == 3.9
72+
73+
- name: Upload distribution package
74+
uses: actions/upload-artifact@master
75+
with:
76+
name: dist-package-${{ matrix.python-version }}
77+
path: dist
78+
if: matrix.python-version == 3.8 || matrix.python-version == 3.9
79+
80+
publish:
81+
runs-on: ubuntu-18.04
82+
needs: build
83+
if: github.event_name == 'release'
84+
steps:
85+
- name: Download a distribution artifact
86+
uses: actions/download-artifact@v2
87+
with:
88+
name: dist-package-3.9
89+
path: dist
90+
- name: Publish distribution 📦 to Test PyPI
91+
uses: pypa/gh-action-pypi-publish@master
92+
with:
93+
skip_existing: true
94+
user: __token__
95+
password: ${{ secrets.test_pypi_password }}
96+
repository_url: https://test.pypi.org/legacy/
97+
- name: Publish distribution 📦 to PyPI
98+
uses: pypa/gh-action-pypi-publish@master
99+
with:
100+
user: __token__
101+
password: ${{ secrets.pypi_password }}

Diff for: CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [1.1.4] - 2020-11-08 :octocat:
9+
- Completely migrates to GitHub Workflows
10+
- Improves build to test Python 3.6 and 3.9
11+
- Improves the `json.FriendlyEncoder` class to handle built-in `dataclasses`
12+
- Adds a changelog
13+
- Improves badges

Diff for: README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
[![Build Status](https://dev.azure.com/robertoprevato/Nest/_apis/build/status/RobertoPrevato.essentials?branchName=master)](https://dev.azure.com/robertoprevato/Nest/_build/latest?definitionId=28&branchName=master) [![pypi](https://img.shields.io/pypi/v/essentials.svg?color=blue)](https://pypi.org/project/essentials/) [![Test coverage](https://img.shields.io/azure-devops/coverage/robertoprevato/Nest/28.svg)](https://dev.azure.com/robertoprevato/Nest/_build?definitionId=28)
1+
![Build](https://github.com/RobertoPrevato/essentials/workflows/Build/badge.svg)
2+
[![pypi](https://img.shields.io/pypi/v/essentials.svg)](https://pypi.python.org/pypi/essentials)
3+
[![versions](https://img.shields.io/pypi/pyversions/essentials.svg)](https://github.com/RobertoPrevato/essentials)
4+
[![license](https://img.shields.io/github/license/RobertoPrevato/essentials.svg)](https://github.com/RobertoPrevato/essentials/blob/master/LICENSE)
25

36
# Essentials
47
Core classes and functions, reusable in any kind of Python application.

Diff for: azure-pipelines.yml

-47
This file was deleted.

Diff for: essentials/json.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,21 @@
22
This module defines a user-friendly json encoder,
33
supporting time objects, UUID and bytes.
44
"""
5-
import json
65
import base64
6+
import dataclasses
7+
import json
8+
from datetime import date, datetime, time
79
from enum import Enum
8-
from datetime import time, date, datetime
910
from uuid import UUID
1011

11-
1212
__all__ = ["FriendlyEncoder", "dumps"]
1313

1414

15-
# TODO: use singledispatch to make the friendly encoder expandable
16-
17-
1815
class FriendlyEncoder(json.JSONEncoder):
1916
def default(self, obj):
2017
try:
2118
return json.JSONEncoder.default(self, obj)
2219
except TypeError:
23-
2420
if hasattr(obj, "dict"):
2521
return obj.dict()
2622
if isinstance(obj, time):
@@ -35,6 +31,8 @@ def default(self, obj):
3531
return str(obj)
3632
if isinstance(obj, Enum):
3733
return obj.value
34+
if dataclasses.is_dataclass(obj):
35+
return dataclasses.asdict(obj)
3836
raise
3937

4038

Diff for: requirements.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ pytest
22
pytest-cov
33
pytest-asyncio
44
flake8
5-
mypy
6-
black
5+
dataclasses==0.7;python_version<'3.7'

Diff for: setup.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,27 @@ def readme():
88

99
setup(
1010
name="essentials",
11-
version="1.1.3",
11+
version="1.1.4",
1212
description="General purpose classes and functions, "
13-
"reusable in any kind of Python application",
13+
"reusable in any kind of Python application",
1414
long_description=readme(),
1515
long_description_content_type="text/markdown",
1616
classifiers=[
1717
"Development Status :: 5 - Production/Stable",
1818
"License :: OSI Approved :: MIT License",
1919
"Programming Language :: Python :: 3",
20+
"Programming Language :: Python :: 3.6",
21+
"Programming Language :: Python :: 3.7",
22+
"Programming Language :: Python :: 3.8",
23+
"Programming Language :: Python :: 3.9",
2024
"Operating System :: OS Independent",
2125
],
2226
url="https://github.com/RobertoPrevato/essentials",
2327
author="RobertoPrevato",
2428
author_email="[email protected]",
2529
keywords="core utilities",
2630
license="MIT",
27-
packages=[
28-
"essentials",
29-
"essentials.typesutils",
30-
"essentials.decorators",
31-
],
32-
install_requires=[],
31+
packages=["essentials", "essentials.typesutils", "essentials.decorators"],
32+
install_requires=["dataclasses==0.7;python_version<'3.7'"],
3333
include_package_data=True,
3434
)

Diff for: tests/test_json.py

+23-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import uuid
1+
from uuid import UUID, uuid4
2+
from dataclasses import dataclass
23
from datetime import date, datetime, time
34
from enum import Enum, Flag, IntEnum, IntFlag, auto
45

@@ -8,8 +9,13 @@
89
from essentials.json import dumps
910

1011

11-
class Fruit(Enum):
12+
@dataclass
13+
class Foo:
14+
id: UUID
15+
name: str
16+
1217

18+
class Fruit(Enum):
1319
ANANAS = "ananas"
1420
BANANA = "banana"
1521
MANGO = "mango"
@@ -42,7 +48,7 @@ class Permission(IntFlag):
4248
({"value": date(2016, 3, 26)}, '{"value": "2016-03-26"}'),
4349
({"value": datetime(2016, 3, 26, 3, 0, 0)}, '{"value": "2016-03-26T03:00:00"}'),
4450
(
45-
{"value": uuid.UUID("e56fddfc-f85b-4178-869f-a218278a639e")},
51+
{"value": UUID("e56fddfc-f85b-4178-869f-a218278a639e")},
4652
'{"value": "e56fddfc-f85b-4178-869f-a218278a639e"}',
4753
),
4854
(
@@ -85,7 +91,6 @@ def __init__(self, x, y):
8591

8692

8793
def test_enum_to_json():
88-
8994
value = dumps(
9095
{
9196
"fruit": Fruit.MANGO,
@@ -98,15 +103,13 @@ def test_enum_to_json():
98103

99104

100105
def test_int_enum_to_json():
101-
102106
value = dumps({"power": Power.GREAT, "powers": [Power.MILD, Power.MODERATE]})
103107

104108
assert '"power": 3' in value
105109
assert '"powers": [1, 2]' in value
106110

107111

108112
def test_intflag_enum_to_json():
109-
110113
value = dumps(
111114
{
112115
"permission_one": Permission.R,
@@ -119,7 +122,6 @@ def test_intflag_enum_to_json():
119122

120123

121124
def test_flag_enum_to_json():
122-
123125
value = dumps(
124126
{
125127
"color_one": Color.GREEN,
@@ -129,3 +131,17 @@ def test_flag_enum_to_json():
129131
)
130132

131133
assert '{"color_one": 4, "color_two": 5, "color_three": 7}' == value
134+
135+
136+
def test_serialize_dataclass():
137+
foo_id = uuid4()
138+
value = dumps(Foo(foo_id, "foo"))
139+
140+
assert f'{{"id": "{foo_id}", "name": "foo"}}' == value
141+
142+
143+
def test_serialize_dataclass_no_spaces():
144+
foo_id = uuid4()
145+
value = dumps(Foo(foo_id, "foo"), separators=(",", ":"))
146+
147+
assert f'{{"id":"{foo_id}","name":"foo"}}' == value

Diff for: tests/test_registry.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
from pytest import raises
22

33
from essentials.exceptions import InvalidArgument
4-
from essentials.registry import (AmbiguousRegistryName, Registry,
5-
TypeNotFoundException)
4+
from essentials.registry import AmbiguousRegistryName, Registry, TypeNotFoundException
65

76

87
def test_registry_type():

0 commit comments

Comments
 (0)