Skip to content

Commit 3616190

Browse files
authored
Merge pull request #30 from nat-n/p36_support
#27 Add support for python 3.6
2 parents 72a77b0 + 9b990ee commit 3616190

File tree

10 files changed

+88
-449
lines changed

10 files changed

+88
-449
lines changed

.github/workflows/ci.yml

+24-3
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,46 @@ name: CI
33
on: [push, pull_request]
44

55
jobs:
6-
build:
6+
7+
run-tests:
78
runs-on: ubuntu-latest
89

10+
strategy:
11+
matrix:
12+
python-version: [ '3.6', '3.7' ]
13+
14+
name: Python ${{ matrix.python-version }} test
15+
916
steps:
1017
- uses: actions/checkout@v1
1118
- uses: actions/setup-python@v1
1219
with:
13-
python-version: 3.7
20+
python-version: ${{ matrix.python-version }}
1421
- uses: dschep/install-pipenv-action@v1
1522
- name: Install dependencies
1623
run: |
1724
sudo apt install protobuf-compiler libprotobuf-dev
18-
pipenv install --dev
25+
pipenv install --dev --python ${pythonLocation}/python
1926
- name: Run tests
2027
run: |
2128
cp .env.default .env
2229
pipenv run pip install -e .
2330
pipenv run generate
2431
pipenv run test
32+
33+
build-release:
34+
runs-on: ubuntu-latest
35+
36+
steps:
37+
- uses: actions/checkout@v1
38+
- uses: actions/setup-python@v1
39+
with:
40+
python-version: 3.7
41+
- uses: dschep/install-pipenv-action@v1
42+
- name: Install dependencies
43+
run: |
44+
sudo apt install protobuf-compiler libprotobuf-dev
45+
pipenv install --dev --python ${pythonLocation}/python
2546
- name: Build package
2647
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
2748
run: pipenv run python setup.py sdist

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
.vscode/settings.json
33
.mypy_cache
44
.pytest_cache
5+
.python-version
6+
build/
57
betterproto/tests/*.bin
68
betterproto/tests/*_pb2.py
79
betterproto/tests/*.py

Pipfile

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,19 @@ mypy = "*"
99
isort = "*"
1010
pytest = "*"
1111
rope = "*"
12+
v = {editable = true,version = "*"}
1213

1314
[packages]
1415
protobuf = "*"
1516
jinja2 = "*"
1617
grpclib = "*"
1718
stringcase = "*"
1819
black = "*"
20+
backports-datetime-fromisoformat = "*"
21+
dataclasses = "*"
1922

2023
[requires]
21-
python_version = "3.7"
24+
python_version = "3.6"
2225

2326
[scripts]
2427
plugin = "protoc --plugin=protoc-gen-custom=betterproto/plugin.py --custom_out=output"

Pipfile.lock

-396
This file was deleted.

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This project aims to provide an improved experience when using Protobuf / gRPC i
66

77
- Protobuf 3 & gRPC code generation
88
- Both binary & JSON serialization is built-in
9-
- Python 3.7+ making use of:
9+
- Python 3.6+ making use of:
1010
- Enums
1111
- Dataclasses
1212
- `async`/`await`
@@ -296,7 +296,7 @@ datetime.datetime(2019, 1, 1, 11, 59, 58, 800000, tzinfo=datetime.timezone.utc)
296296

297297
## Development
298298

299-
First, make sure you have Python 3.7+ and `pipenv` installed, along with the official [Protobuf Compiler](https://github.com/protocolbuffers/protobuf/releases) for your platform. Then:
299+
First, make sure you have Python 3.6+ and `pipenv` installed, along with the official [Protobuf Compiler](https://github.com/protocolbuffers/protobuf/releases) for your platform. Then:
300300

301301
```sh
302302
# Get set up with the virtual env & dependencies

betterproto/__init__.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import inspect
44
import json
55
import struct
6+
import sys
67
from abc import ABC
78
from base64 import b64encode, b64decode
89
from datetime import datetime, timedelta, timezone
@@ -33,6 +34,13 @@
3334
if TYPE_CHECKING:
3435
from grpclib._protocols import IProtoMessage
3536

37+
if not (sys.version_info.major == 3 and sys.version_info.minor >= 7):
38+
# Apply backport of datetime.fromisoformat from 3.7
39+
from backports.datetime_fromisoformat import MonkeyPatch
40+
41+
MonkeyPatch.patch_fromisoformat()
42+
43+
3644
# Proto 3 data types
3745
TYPE_ENUM = "enum"
3846
TYPE_BOOL = "bool"
@@ -569,10 +577,10 @@ def _get_field_default(self, field: dataclasses.Field, meta: FieldMetadata) -> A
569577

570578
value: Any = 0
571579
if hasattr(t, "__origin__"):
572-
if t.__origin__ == dict:
580+
if t.__origin__ in (dict, Dict):
573581
# This is some kind of map (dict in Python).
574582
value = {}
575-
elif t.__origin__ == list:
583+
elif t.__origin__ in (list, List):
576584
# This is some kind of list (repeated) field.
577585
value = []
578586
elif t.__origin__ == Union and t.__args__[1] == type(None):
@@ -704,7 +712,9 @@ def parse(self: T, data: bytes) -> T:
704712
def FromString(cls: Type[T], data: bytes) -> T:
705713
return cls().parse(data)
706714

707-
def to_dict(self, casing: Casing = Casing.CAMEL, include_default_values: bool = False) -> dict:
715+
def to_dict(
716+
self, casing: Casing = Casing.CAMEL, include_default_values: bool = False
717+
) -> dict:
708718
"""
709719
Returns a dict representation of this message instance which can be
710720
used to serialize to e.g. JSON. Defaults to camel casing for
-2.97 KB
Binary file not shown.

betterproto/tests/test_features.py

+35-41
Original file line numberDiff line numberDiff line change
@@ -191,25 +191,22 @@ class TestMessage(betterproto.Message):
191191
test = TestMessage().from_dict({})
192192

193193
assert test.to_dict(include_default_values=True) == {
194-
'someInt': 0,
195-
'someDouble': 0.0,
196-
'someStr': '',
197-
'someBool': False
194+
"someInt": 0,
195+
"someDouble": 0.0,
196+
"someStr": "",
197+
"someBool": False,
198198
}
199199

200200
# All default values
201-
test = TestMessage().from_dict({
202-
'someInt': 0,
203-
'someDouble': 0.0,
204-
'someStr': '',
205-
'someBool': False
206-
})
201+
test = TestMessage().from_dict(
202+
{"someInt": 0, "someDouble": 0.0, "someStr": "", "someBool": False}
203+
)
207204

208205
assert test.to_dict(include_default_values=True) == {
209-
'someInt': 0,
210-
'someDouble': 0.0,
211-
'someStr': '',
212-
'someBool': False
206+
"someInt": 0,
207+
"someDouble": 0.0,
208+
"someStr": "",
209+
"someBool": False,
213210
}
214211

215212
# Some default and some other values
@@ -224,26 +221,28 @@ class TestMessage2(betterproto.Message):
224221
some_default_str: str = betterproto.string_field(7)
225222
some_default_bool: bool = betterproto.bool_field(8)
226223

227-
test = TestMessage2().from_dict({
228-
'someInt': 2,
229-
'someDouble': 1.2,
230-
'someStr': 'hello',
231-
'someBool': True,
232-
'someDefaultInt': 0,
233-
'someDefaultDouble': 0.0,
234-
'someDefaultStr': '',
235-
'someDefaultBool': False
236-
})
224+
test = TestMessage2().from_dict(
225+
{
226+
"someInt": 2,
227+
"someDouble": 1.2,
228+
"someStr": "hello",
229+
"someBool": True,
230+
"someDefaultInt": 0,
231+
"someDefaultDouble": 0.0,
232+
"someDefaultStr": "",
233+
"someDefaultBool": False,
234+
}
235+
)
237236

238237
assert test.to_dict(include_default_values=True) == {
239-
'someInt': 2,
240-
'someDouble': 1.2,
241-
'someStr': 'hello',
242-
'someBool': True,
243-
'someDefaultInt': 0,
244-
'someDefaultDouble': 0.0,
245-
'someDefaultStr': '',
246-
'someDefaultBool': False
238+
"someInt": 2,
239+
"someDouble": 1.2,
240+
"someStr": "hello",
241+
"someBool": True,
242+
"someDefaultInt": 0,
243+
"someDefaultDouble": 0.0,
244+
"someDefaultStr": "",
245+
"someDefaultBool": False,
247246
}
248247

249248
# Nested messages
@@ -257,15 +256,10 @@ class TestParentMessage(betterproto.Message):
257256
some_double: float = betterproto.double_field(2)
258257
some_message: TestChildMessage = betterproto.message_field(3)
259258

260-
test = TestParentMessage().from_dict({
261-
'someInt': 0,
262-
'someDouble': 1.2,
263-
})
259+
test = TestParentMessage().from_dict({"someInt": 0, "someDouble": 1.2,})
264260

265261
assert test.to_dict(include_default_values=True) == {
266-
'someInt': 0,
267-
'someDouble': 1.2,
268-
'someMessage': {
269-
'someOtherInt': 0
270-
}
262+
"someInt": 0,
263+
"someDouble": 1.2,
264+
"someMessage": {"someOtherInt": 0},
271265
}

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tool.black]
2-
target-version = ['py37']
2+
target-version = ['py36']
33

44
[tool.isort]
55
multi_line_output = 3

setup.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@
1717
exclude=["tests", "*.tests", "*.tests.*", "output", "output.*"]
1818
),
1919
package_data={"betterproto": ["py.typed", "templates/template.py"]},
20-
python_requires=">=3.7",
21-
install_requires=["grpclib", "stringcase"],
20+
python_requires=">=3.6",
21+
install_requires=[
22+
'dataclasses; python_version<"3.7"',
23+
'backports-datetime-fromisoformat; python_version<"3.7"',
24+
"grpclib",
25+
"stringcase",
26+
],
2227
extras_require={"compiler": ["black", "jinja2", "protobuf"]},
2328
zip_safe=False,
2429
)

0 commit comments

Comments
 (0)