Skip to content

Commit

Permalink
Merge pull request #336 from cleder/264-test-documentation-with-docte…
Browse files Browse the repository at this point in the history
…st-usage-guide-is-broken-for-version-1x

add docstrings and fixes for ruff
  • Loading branch information
cleder authored Jul 18, 2024
2 parents 6e90a52 + 0e30b63 commit 9e954cf
Show file tree
Hide file tree
Showing 17 changed files with 2,499 additions and 244 deletions.
153 changes: 120 additions & 33 deletions fastkml/atom.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

"""
Basic Atom support for KML.
KML 2.2 supports new elements for including data about the author and related
website in your KML file. This information is displayed in geo search results,
both in Earth browsers such as Google Earth, and in other applications such as
Expand Down Expand Up @@ -72,39 +74,21 @@ def get_tag_name(cls) -> str:

class Link(_AtomObject):
"""
Identifies a related Web page. The rel attribute defines the type of relation.
Identifies a related Web page.
The rel attribute defines the type of relation.
A feed is limited to one alternate per type and hreflang.
<link> is patterned after html's link element. It has one required
attribute, href, and five optional attributes: rel, type, hreflang,
title, and length.
"""

href: Optional[str]
# href is the URI of the referenced resource

rel: Optional[str]
# rel contains a single link relationship type.
# It can be a full URI, or one of the following predefined values
# (default=alternate):
# alternate: an alternate representation
# enclosure: a related resource which is potentially large in size
# and might require special handling, for example an audio or video
# recording.
# related: an document related to the entry or feed.
# self: the feed itself.
# via: the source of the information provided in the entry.

type: Optional[str]
# indicates the media type of the resource

hreflang: Optional[str]
# indicates the language of the referenced resource

title: Optional[str]
# human readable information about the link

length: Optional[int]
# the length of the resource, in bytes

def __init__(
self,
Expand All @@ -118,6 +102,37 @@ def __init__(
length: Optional[int] = None,
**kwargs: Any,
) -> None:
"""
Initialize a Link object.
Parameters
----------
ns : str, optional
The namespace of the Link object.
name_spaces : dict, optional
The dictionary of namespace prefixes and URIs.
href : str, optional
The URI of the referenced resource.
rel : str, optional
The link relationship type. It can be a full URI or one of the
following predefined values: 'alternate', 'enclosure', 'related',
'self', or 'via'.
type : str, optional
The media type of the resource.
hreflang : str, optional
The language of the referenced resource.
title : str, optional
Human-readable information about the link.
length : int, optional
The length of the resource in bytes.
kwargs : dict, optional
Additional keyword arguments.
Returns
-------
None
"""
super().__init__(ns=ns, name_spaces=name_spaces, **kwargs)
self.href = href
self.rel = rel
Expand All @@ -127,7 +142,15 @@ def __init__(
self.length = length

def __repr__(self) -> str:
"""Create a string (c)representation for Link."""
"""
Return a string representation of the Link object.
Returns
-------
str
The string representation of the Link object.
"""
return (
f"{self.__class__.__module__}.{self.__class__.__name__}("
f"ns={self.ns!r}, "
Expand All @@ -143,11 +166,34 @@ def __repr__(self) -> str:
)

def __bool__(self) -> bool:
"""
Check if the Link object is truthy.
Returns
-------
bool
True if the Link object has a href attribute, False otherwise.
"""
return bool(self.href)

def __eq__(self, other: object) -> bool:
"""
Check if the Link object is equal to another object.
Parameters
----------
other : object
The object to compare with.
Returns
-------
bool
True if the Link object is equal to the other object, False otherwise.
"""
try:
assert isinstance(other, type(self))
assert isinstance(other, type(self)) # noqa: S101
except AssertionError:
return False
return (
Expand Down Expand Up @@ -232,19 +278,19 @@ def __eq__(self, other: object) -> bool:

class _Person(_AtomObject):
"""
<author> and <contributor> describe a person, corporation, or similar
entity. It has one required element, name, and two optional elements:
uri, email.
Represents a person, corporation, or similar entity.
Attributes
----------
name (Optional[str]): A human-readable name for the person.
uri (Optional[str]): A home page for the person.
email (Optional[str]): An email address for the person.
"""

name: Optional[str]
# conveys a human-readable name for the person.

uri: Optional[str]
# contains a home page for the person.

email: Optional[str]
# contains an email address for the person.

def __init__(
self,
Expand All @@ -255,13 +301,33 @@ def __init__(
email: Optional[str] = None,
**kwargs: Any,
) -> None:
"""
Initialize a new instance of the _Person class.
Args:
----
ns (Optional[str]): The namespace for the XML element.
name_spaces (Optional[Dict[str, str]]): The namespace dictionary.
name (Optional[str]): A human-readable name for the person.
uri (Optional[str]): A home page for the person.
email (Optional[str]): An email address for the person.
**kwargs: Additional keyword arguments.
"""
super().__init__(ns=ns, name_spaces=name_spaces, **kwargs)
self.name = name
self.uri = uri
self.email = email

def __repr__(self) -> str:
"""Create a string (c)representation for _Person."""
"""
Return a string representation of the _Person object.
Returns
-------
str: The string representation of the _Person object.
"""
return (
f"{self.__class__.__module__}.{self.__class__.__name__}("
f"ns={self.ns!r}, "
Expand All @@ -274,11 +340,32 @@ def __repr__(self) -> str:
)

def __bool__(self) -> bool:
"""
Check if the _Person object has a name.
Returns
-------
bool: True if the _Person object has a name, False otherwise.
"""
return bool(self.name)

def __eq__(self, other: object) -> bool:
"""
Check if the _Person object is equal to another object.
Args:
----
other (object): The object to compare with.
Returns:
-------
bool: True if the _Person object is equal to the other object,
False otherwise.
"""
try:
assert isinstance(other, type(self))
assert isinstance(other, type(self)) # noqa: S101
except AssertionError:
return False
return (
Expand Down
66 changes: 58 additions & 8 deletions fastkml/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@

class _Container(_Feature):
"""
abstract element; do not create
A Container element holds one or more Features and allows the
creation of nested hierarchies.
A Container element that holds one or more Features.
Supports the creation of nested hierarchies.
subclasses are:
Document,
Folder.
Expand Down Expand Up @@ -155,21 +155,23 @@ def append(self, kmlobj: _Feature) -> None:
if kmlobj is self:
msg = "Cannot append self"
raise ValueError(msg)
assert self.features is not None
assert self.features is not None # noqa: S101
self.features.append(kmlobj)


class Folder(_Container):
"""
A Folder is used to arrange other Features hierarchically
(Folders, Placemarks, #NetworkLinks, or #Overlays).
A Folder is used to arrange other Features hierarchically.
It may contain Folders, Placemarks, NetworkLinks, or Overlays.
"""


class Document(_Container):
"""
A Document is a container for features and styles. This element is
required if your KML file uses shared styles or schemata for typed
A Document is a container for features and styles.
This element is required if your KML file uses shared styles or schemata for typed
extended data.
"""

Expand Down Expand Up @@ -200,6 +202,40 @@ def __init__(
schemata: Optional[Iterable[Schema]] = None,
**kwargs: Any,
) -> None:
"""
Initialize a new instance of the class.
Args:
----
ns (Optional[str]): The namespace.
name_spaces (Optional[Dict[str, str]]):
The dictionary of namespace prefixes and URIs.
id (Optional[str]): The ID of the container.
target_id (Optional[str]): The target ID.
name (Optional[str]): The name of the container.
visibility (Optional[bool]): The visibility flag.
isopen (Optional[bool]): The isopen flag.
atom_link (Optional[atom.Link]): The Atom link.
atom_author (Optional[atom.Author]): The Atom author.
address (Optional[str]): The address.
phone_number (Optional[str]): The phone number.
snippet (Optional[Snippet]): The snippet.
description (Optional[str]): The description.
view (Optional[Union[Camera, LookAt]]): The view.
times (Optional[Union[TimeSpan, TimeStamp]]): The times.
style_url (Optional[StyleUrl]): The style URL.
styles (Optional[Iterable[Union[Style, StyleMap]]]): The styles.
region (Optional[Region]): The region.
extended_data (Optional[ExtendedData]): The extended data.
features (Optional[List[_Feature]]): The list of features.
schemata (Optional[Iterable[Schema]]): The schemata.
**kwargs (Any): Additional keyword arguments.
Returns:
-------
None
"""
super().__init__(
ns=ns,
name_spaces=name_spaces,
Expand Down Expand Up @@ -255,6 +291,20 @@ def __repr__(self) -> str:
)

def get_style_by_url(self, style_url: str) -> Optional[Union[Style, StyleMap]]:
"""
Get a style by URL.
Parameters
----------
style_url : str
The URL of the style.
Returns
-------
Optional[Union[Style, StyleMap]]
The style object if found, otherwise None.
"""
id_ = urlparse.urlparse(style_url).fragment
return next((style for style in self.styles if style.id == id_), None)

Expand Down
Loading

0 comments on commit 9e954cf

Please sign in to comment.