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 Registry to abstract serializing and deserialzing xml into kml objects #296

Merged
merged 38 commits into from
Jan 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
11a1a2d
introduce a registry
cleder Dec 23, 2023
4549d60
Add introspection utilities for getting type hints in class constructors
cleder Dec 23, 2023
5f3debb
Add registry functionality for XMLObject attributes
cleder Dec 27, 2023
a711f5a
Standardize call args
cleder Dec 27, 2023
0ebb65d
Standardize call args
cleder Dec 28, 2023
60a48cd
Use registry.register in geometry.py, fix helpers usgage
cleder Dec 28, 2023
8763757
fix edgecase for gx:elements
cleder Dec 28, 2023
7a896b6
Refactor gx.py: Remove unused methods and update class registration
cleder Dec 28, 2023
141bc5b
Refactor XML parsing code to support additional data types
cleder Dec 28, 2023
95e9f1e
Refactor atom.py Register _Person attributes in fastkml.registry
cleder Dec 28, 2023
cf86f57
Merge branch 'develop' into registry
cleder Dec 28, 2023
9c5fef6
Add class introspection and registry creation
cleder Dec 29, 2023
7abcd16
create registry for views.py with introspect.py
cleder Dec 29, 2023
24a99a1
create registry for styles.py with introspect.py
cleder Dec 30, 2023
4759792
create registry for features.py with introspect.py
cleder Dec 30, 2023
ca60b81
refactor containers to use the registry
cleder Dec 31, 2023
d19699b
fix data tests
cleder Dec 31, 2023
3f7169e
refactor overlays to use registry
cleder Dec 31, 2023
e01eaba
refactor data.py to use registry
cleder Dec 31, 2023
5a86133
Refactor __bool__ method in Data class
cleder Dec 31, 2023
f0fcd19
Refactor ExtendedData class to use registry for subelements
cleder Dec 31, 2023
511ff88
annotate namespace keys as final
cleder Dec 31, 2023
9296e9e
flake8 min python version is 3.8
cleder Dec 31, 2023
6a46229
Update Python versions in GitHub Actions workflow
cleder Dec 31, 2023
047e314
no lxml for python 3.13 yet
cleder Dec 31, 2023
e3a4dc2
stricter type annotations, remove Optional
cleder Dec 31, 2023
4165a0a
Refactor subelement helper functions name_spaces parameter is no long…
cleder Dec 31, 2023
842ff1c
remove unused code
cleder Jan 1, 2024
cf8f141
Exclude additional lines from coverage report
cleder Jan 2, 2024
881c2a6
Exclude ellipsis from coverage report
cleder Jan 2, 2024
93b7f19
Refactor xml_subelement_list function to handle empty items
cleder Jan 2, 2024
c806651
Add __repr__ methods to classes in styles.py
cleder Jan 3, 2024
d0700ed
Add __repr__ methods to classes in links.py
cleder Jan 3, 2024
13bb78a
Remove Codeball workflow
cleder Jan 3, 2024
d30093a
Test NetworkLink
cleder Jan 3, 2024
6bff022
Test Placemark geometry parameters
cleder Jan 3, 2024
ac2acb1
fix typos, ignore import errors in coverage
cleder Jan 4, 2024
53661f0
ommit empty styles
cleder Jan 4, 2024
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
12 changes: 0 additions & 12 deletions .github/workflows/codeball.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/run-all-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
# run tests and lint with a variety of Python versions
---
name: Tests
on: [push, pull_request]

Check warning on line 5 in .github/workflows/run-all-tests.yml

View workflow job for this annotation

GitHub Actions / static-tests (3.12)

5:1 [truthy] truthy value should be one of [false, true]

Check warning on line 5 in .github/workflows/run-all-tests.yml

View workflow job for this annotation

GitHub Actions / static-tests (3.12)

5:1 [truthy] truthy value should be one of [false, true]

jobs:
cpython:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13-dev']

steps:
- uses: actions/checkout@v4
Expand Down
125 changes: 33 additions & 92 deletions fastkml/atom.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
from fastkml.enums import Verbosity
from fastkml.helpers import subelement_text_kwarg
from fastkml.helpers import text_subelement
from fastkml.registry import RegistryItem
from fastkml.registry import registry
from fastkml.types import Element

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -121,19 +123,6 @@ def __init__(
self.title = title
self.length = length

def __repr__(self) -> str:
return (
f"{self.__class__.__name__}("
f"ns={self.ns!r}, "
f"href={self.href!r}, "
f"rel={self.rel!r}, "
f"type={self.type!r}, "
f"hreflang={self.hreflang!r}, "
f"title={self.title!r}, "
f"length={self.length!r}, "
")"
)

def __bool__(self) -> bool:
return bool(self.href)

Expand Down Expand Up @@ -180,7 +169,7 @@ def _get_kwargs(
kwargs["hreflang"] = element.get("hreflang")
kwargs["title"] = element.get("title")
length = element.get("length")
kwargs["length"] = int(length) if length else None
kwargs["length"] = int(length) if length and length.strip() else None
return kwargs


Expand Down Expand Up @@ -213,88 +202,40 @@ def __init__(
self.uri = uri
self.email = email

def __repr__(self) -> str:
return (
f"{self.__class__.__name__}("
f"ns={self.ns!r}, "
f"name={self.name!r}, "
f"uri={self.uri!r}, "
f"email={self.email!r}, "
")"
)

def __bool__(self) -> bool:
return bool(self.name)

def etree_element(
self,
precision: Optional[int] = None,
verbosity: Verbosity = Verbosity.normal,
) -> Element:
element = super().etree_element(precision=precision, verbosity=verbosity)
text_subelement(
self,
element=element,
attr_name="name",
node_name="name",
)
text_subelement(
self,
element=element,
attr_name="uri",
node_name="uri",
)
text_subelement(
self,
element=element,
attr_name="email",
node_name="email",
)
return element

@classmethod
def _get_kwargs(
cls,
*,
ns: str,
name_spaces: Optional[Dict[str, str]] = None,
element: Element,
strict: bool,
) -> Dict[str, Any]:
kwargs = super()._get_kwargs(
ns=ns,
name_spaces=name_spaces,
element=element,
strict=strict,
)
kwargs.update(
subelement_text_kwarg(
element=element,
ns=ns,
node_name="name",
kwarg="name",
strict=strict,
),
)
kwargs.update(
subelement_text_kwarg(
element=element,
ns=ns,
node_name="uri",
kwarg="uri",
strict=strict,
),
)
kwargs.update(
subelement_text_kwarg(
element=element,
ns=ns,
node_name="email",
kwarg="email",
strict=strict,
),
)
return kwargs
registry.register(
_Person,
item=RegistryItem(
attr_name="name",
node_name="name",
classes=(str,),
get_kwarg=subelement_text_kwarg,
set_element=text_subelement,
),
)
registry.register(
_Person,
item=RegistryItem(
attr_name="uri",
node_name="uri",
classes=(str,),
get_kwarg=subelement_text_kwarg,
set_element=text_subelement,
),
)
registry.register(
_Person,
item=RegistryItem(
attr_name="email",
node_name="email",
classes=(str,),
get_kwarg=subelement_text_kwarg,
set_element=text_subelement,
),
)


class Author(_Person):
Expand Down
22 changes: 22 additions & 0 deletions fastkml/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

from fastkml import config
from fastkml.enums import Verbosity
from fastkml.registry import registry
from fastkml.types import Element

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -60,6 +61,15 @@ def etree_element(
element: Element = config.etree.Element( # type: ignore[attr-defined]
f"{self.ns}{self.get_tag_name()}",
)
for item in registry.get(self.__class__):
item.set_element(
obj=self,
element=element,
attr_name=item.attr_name,
node_name=item.node_name,
precision=precision,
verbosity=verbosity,
)
return element

def to_string(
Expand Down Expand Up @@ -117,6 +127,18 @@ def _get_kwargs(
name_spaces = name_spaces or {}
name_spaces = {**config.NAME_SPACES, **name_spaces}
kwargs: Dict[str, Any] = {"ns": ns, "name_spaces": name_spaces}
for item in registry.get(cls):
kwargs.update(
item.get_kwarg(
element=element,
ns=ns,
name_spaces=name_spaces,
node_name=item.node_name,
kwarg=item.attr_name,
classes=item.classes,
strict=strict,
),
)
return kwargs

@classmethod
Expand Down
11 changes: 8 additions & 3 deletions fastkml/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import logging
import warnings
from types import ModuleType
from typing import Final

__all__ = [
"ATOMNS",
Expand Down Expand Up @@ -46,14 +47,18 @@ def set_etree_implementation(implementation: ModuleType) -> None:
etree = implementation


KML: Final = "kml"
ATOM: Final = "atom"
GX: Final = "gx"

KMLNS = "{http://www.opengis.net/kml/2.2}"
ATOMNS = "{http://www.w3.org/2005/Atom}"
GXNS = "{http://www.google.com/kml/ext/2.2}"

NAME_SPACES = {
"kml": KMLNS,
"atom": ATOMNS,
"gx": GXNS,
KML: KMLNS,
ATOM: ATOMNS,
GX: GXNS,
}


Expand Down
Loading
Loading