Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type hints #162

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
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
26 changes: 25 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,28 @@ repos:
rev: 6.0.0
hooks:
- id: flake8

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: no-commit-to-branch
- id: check-merge-conflict
- id: check-symlinks
- id: mixed-line-ending
args: ['--fix=no']
- id: check-ast
- id: check-builtin-literals
- id: check-case-conflict
- id: check-docstring-first
- repo: https://github.com/asottile/pyupgrade
rev: v3.9.0
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: local
hooks:
- id: mypy
name: mypy
entry: mypy
language: python
pass_filenames: false
files: '.*\.py$'
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"[python]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "charliermarsh.ruff"
}
}
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ format: ## Format source code (black codestyle)
lint: ## Linting of source code
python -m black --check --diff osmapi examples tests *.py
python -m flake8 --statistics --show-source .
python -m mypy --strict

test: ## Run tests (run in UTF-8 mode in Windows)
python -Xutf8 -m pytest --cov=osmapi tests/
Expand Down
39 changes: 21 additions & 18 deletions osmapi/OsmApi.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

"""

from typing import Union, List
from typing_extensions import Self
import xml.dom.minidom
import xml.parsers.expat
import urllib.parse
Expand All @@ -37,6 +39,7 @@
from . import errors
from . import http
from . import parser
from . import types
from . import xmlbuilder


Expand All @@ -49,19 +52,19 @@ class OsmApi:
"""

def __init__(
self,
username=None,
password=None,
passwordfile=None,
appid="",
created_by=f"osmapi/{__version__}",
api="https://www.openstreetmap.org",
changesetauto=False,
changesetautotags={},
changesetautosize=500,
changesetautomulti=1,
session=None,
):
self: Self,
username: str | None = None,
password: str | None = None,
passwordfile: str | None = None,
appid: str = "",
created_by: str = f"osmapi/{__version__}",
api: str = "https://www.openstreetmap.org",
changesetauto: bool = False,
changesetautotags: dict = {},
changesetautosize: int = 500,
changesetautomulti: int = 1,
session: types.SessionLike | None = None,
) -> None:
"""
Initialized the OsmApi object.

Expand Down Expand Up @@ -128,7 +131,7 @@ def __init__(
self._changesetautomulti = changesetautomulti
self._changesetautocpt = 0
# data to upload for auto group
self._changesetautodata = []
self._changesetautodata: List[types.ChangesetDataDict] = []

# Get API
self._api = api.strip("/")
Expand All @@ -151,13 +154,13 @@ def __init__(
self._api, self._created_by, auth=auth, session=self.http_session
)

def __enter__(self):
def __enter__(self) -> Self:
self._session = http.OsmApiSession(
self._api, self._created_by, session=self.http_session
)
return self

def __exit__(self, *args):
def __exit__(self, *args) -> None:
self.close()

def close(self):
Expand All @@ -174,7 +177,7 @@ def close(self):
# Capabilities #
##################################################

def Capabilities(self):
def Capabilities(self) -> types.CapabilitiesDict:
"""
Returns the API capabilities as a dict:

Expand Down Expand Up @@ -229,7 +232,7 @@ def Capabilities(self):
# Node #
##################################################

def NodeGet(self, NodeId, NodeVersion=-1):
def NodeGet(self, NodeId: Union[str, int], NodeVersion: int = -1):
"""
Returns node with `NodeId` as a dict:

Expand Down
89 changes: 89 additions & 0 deletions osmapi/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from typing import Literal, TypedDict, List, Dict, Any, Protocol

# from typing import Literal, List, Optional, TypedDict, Dict

id_type = int
OsmType = Literal["node", "way", "relation"]


class MaxDict(TypedDict):
maximum: int


class MinDict(TypedDict):
minimum: int


class MinMaxDict(MaxDict, MinDict):
pass


class ChangesetsDict(TypedDict):
maximum_elements: int


class StatusDict(TypedDict):
api: Literal["online", "readonly", "offline"]
database: Literal["online", "readonly", "offline"]
gpx: Literal["online", "readonly", "offline"]


class TimeoutDict(TypedDict):
seconds: int


class TracepointsDict(TypedDict):
per_page: int


class CapabilitiesDict(TypedDict):
area: MaxDict
changesets: ChangesetsDict
status: StatusDict
timeout: TimeoutDict
tracepoints: TracepointsDict
version: MinMaxDict
waynodes: MaxDict


class RelationMemberDict(TypedDict):
ref: id_type
role: str # TODO: how many roles are there?
type: OsmType


class RealtionData(TypedDict):
id: id_type
member: List[RelationMemberDict]
tag: Dict
changeset: id_type
version: int
user: str
uid: id_type
visible: bool


OsmData = RealtionData


class ChangesetDataDict(TypedDict):
action: Literal["delete", "", ""]
type: OsmType
data: OsmData


class ChangesetTagsDict(TypedDict):
str: str


class HttpResponse:
status_code: int
content: str
reason: str


class SessionLike(Protocol):
auth: Any
headers: dict

def request(method: str, path: str, data: dict) -> HttpResponse: ...
6 changes: 6 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ disable_noqa = False
# adaptions for black
max-line-length = 88
extend-ignore = E203

[mypy]
ignore_missing_imports = True
install_types = on
non_interactive = on
files = osmapi/*.py
6 changes: 2 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
# -*- coding: utf-8 -*-

from codecs import open
from setuptools import setup, find_packages
import re

with open("osmapi/__init__.py", "r") as fd:
with open("osmapi/__init__.py") as fd:
version = re.search(
r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE
).group(1)

if not version:
raise RuntimeError("Cannot find version information")

with open("README.md", "r", encoding="utf-8") as f:
with open("README.md", encoding="utf-8") as f:
long_description = f.read()

setup(
Expand Down
1 change: 1 addition & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ responses
coverage
black
pre-commit
mypy
Loading