Skip to content

Commit

Permalink
install pydocstyle and update docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
mscarey committed Jun 8, 2019
1 parent 8d2f161 commit a628fcd
Show file tree
Hide file tree
Showing 15 changed files with 287 additions and 94 deletions.
3 changes: 3 additions & 0 deletions .pydocstyle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pydocstyle]

add-ignore=D105,D202,D301
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ authorityspoke = {path = ".",editable = true}
[dev-packages]
black = "*"
mypy = "*"
pydocstyle = "*"
pylint = "*"
pytest = "*"
pytest-cov = "*"
Expand Down
18 changes: 17 additions & 1 deletion Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions authorityspoke/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@ def wrapper(

def get_directory_path(stem: str) -> pathlib.Path:
"""
This function finds a data directory for importing files, if
the current working directory is that directory, is its
parent directory, or is a sibling
directory. Otherwise it won't find the right directory.
Find a data directory for importing files.
Will only find the correct directory if it is the current working
directory is that directory, is its child directory, or is a sibling
directory. Requires the directory to be found within an ``example_data``
directory.
This function doesn't obviously belong in the context module.
Expand Down
60 changes: 42 additions & 18 deletions authorityspoke/enactments.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Classes representing legislation."""

from __future__ import annotations

import datetime
Expand All @@ -18,7 +20,9 @@

class Code:
"""
A constitution, code of statutes, code of regulations,
A code of legislation.
Could be a constitution, code of statutes, code of regulations,
or collection of court rules.
Each instance of this class depends on an XML file containing
Expand All @@ -45,15 +49,19 @@ def __init__(self, filename: str):
@property
def path(self):
"""
Construct the path to this file in the ``example_data`` folder.
:returns:
The path to the file where the XML file for
the code can be found.
"""
return self.__class__.directory / self.filename

@lazyprop
@property
def jurisdiction(self) -> str:
"""
Get string representing the jurisdiction from within ``uri``.
:returns:
The abbreviation for the jurisdiction that
enacted the ``Code``, in USLM-like format.
Expand All @@ -66,10 +74,11 @@ def jurisdiction(self) -> str:
@property
def level(self) -> str:
"""
Get identifier for the :class:`.Enactment` type found in this ``Code``.
:returns:
"constitution", "statute", or "regulation"
"""

if "Constitution" in self.title:
return "constitution"
elif "Regulations" in self.title:
Expand All @@ -80,13 +89,14 @@ def level(self) -> str:
@lazyprop
def title(self) -> str:
"""
Provide "title" identifier for the ``Code``'s XML.
:returns:
the contents of an XML ``title`` element that
describes the ``Code``, if any. Otherwise
returns a descriptive name that may not exactly
appear in the XML.
"""

uslm_title = self.xml.find("dc:title")
if uslm_title:
return uslm_title.text
Expand All @@ -102,6 +112,8 @@ def title(self) -> str:
@lazyprop
def uri(self) -> str:
"""
Build a URI for the ``Code`` based on its XML metadata.
.. note::
This handles California state statutes only with a
mockup, which can only refer to the Penal and Evidence
Expand Down Expand Up @@ -132,6 +144,8 @@ def uri(self) -> str:
@lazyprop
def xml(self):
"""
Get XML tree of legislative provisions.
:returns:
A BeautifulSoup object created by parsing the
``Code``\'s XML file
Expand All @@ -142,6 +156,8 @@ def xml(self):

def format_uri_for_const(self, uri: str) -> str:
"""
Convert ``uri`` to identifier for constitution sections.
Although the US Constitution is published in a format
described as USML, its section identifier strings differ from
those in USC USML documents in that they skip the jurisdiction
Expand All @@ -168,6 +184,8 @@ def provision_effective_date(
self, cite: Union[TextQuoteSelector, str]
) -> datetime.date:
"""
Give effective date for a provision within the ``Code``.
So far this method only covers the US Constitution and it
assumes that the XML format is `United States Legislative
Markup (USLM) <https://github.com/usgpo/uslm>`_.
Expand All @@ -179,7 +197,6 @@ def provision_effective_date(
:returns:
the effective date of the cited provision
"""

if isinstance(cite, TextQuoteSelector):
cite = cite.path
if self.level == "constitution" and self.jurisdiction == "us":
Expand Down Expand Up @@ -211,6 +228,8 @@ def provision_effective_date(

def select_text(self, selector: TextQuoteSelector) -> Optional[str]:
"""
Get text from the ``Code`` using a :class:`.TextQuoteSelector`.
:param selector:
a selector referencing a text passage in the ``Code``.
Expand All @@ -228,8 +247,7 @@ def select_text(self, selector: TextQuoteSelector) -> Optional[str]:

def cal_href(docpath, href):
"""
Tests whether an XML element has an attribute labeling it as the text
of the statutory section `self.section`.
Test if XML element is labeled as the text of the section in ``docpath``.
Uses `California statute XML format <http://leginfo.legislature.ca.gov/>`_.
"""
Expand Down Expand Up @@ -289,9 +307,10 @@ def __str__(self):

@dataclass(frozen=True)
class Enactment:

"""
A passage of legislative text. May be used as support for a
A passage of legislative text.
May be used as support for a
:class:`.ProceduralRule`. To retrieve the text, there needs
to be an available method for identifying the correct XML
element based on the section and subsection names, and each
Expand Down Expand Up @@ -330,6 +349,8 @@ def __post_init__(self):
@property
def effective_date(self):
"""
Give effective date for the :class:`Enactment`\.
:returns:
the effective date of the text in this passage.
Currently works only for the US Constitution.
Expand All @@ -354,8 +375,7 @@ def from_dict(
**kwargs,
) -> Enactment:
"""
Creates a new :class:`Enactment` object using a :class:`dict`
imported from JSON example data.
Create a new :class:`Enactment` object using imported JSON data.
The new :class:`Enactment` can be composed from a :class:`.Code`
referenced in the ``regime`` parameter.
Expand All @@ -364,7 +384,7 @@ def from_dict(
:param regime:
the :class:`.Regime` where the :class:`.Code` that is the
source for this ``Enactment`` can be found.
source for this :class:`Enactment` can be found.
"""
# TODO: allow 'code' as a parameter
code = None
Expand Down Expand Up @@ -393,9 +413,11 @@ def from_dict(

def means(self, other: Enactment) -> bool:
"""
Whether the meaning of ``self`` is equivalent to (neither
broader nor narrower than) the meaning of the legislative
text passage ``other``.
Find whether meaning of ``self`` is equivalent to that of ``other``.
``Self`` must be neither broader nor narrower than ``other``, which
means it must contain the same legislative text in the same :class:`.Code`
from the same :class:`.Jurisdiction`
.. note::
You could always make the result ``False`` by comparing longer
Expand All @@ -406,7 +428,7 @@ def means(self, other: Enactment) -> bool:
:returns:
whether ``self`` and ``other`` represent the same text
issued by the same sovereign in the same level of
:class:`Enactment`.
:class:`Enactment`\.
"""
if not isinstance(other, self.__class__):
return False
Expand All @@ -422,6 +444,8 @@ def __str__(self):

def __ge__(self, other):
"""
Tells whether ``self`` implies ``other``.
.. note::
Why does this method not require the same ``code.sovereign``
and ``code.level``, especially considering that
Expand All @@ -431,7 +455,6 @@ def __ge__(self, other):
Whether ``self`` "implies" ``other``, which in this context means
whether ``self`` contains at least all the same text as ``other``.
"""

if not isinstance(other, self.__class__):
raise TypeError(
f"{self.__class__} objects may only be compared for "
Expand All @@ -440,7 +463,8 @@ def __ge__(self, other):

return other.text.strip(",:;. ") in self.text

def __gt__(self, other):
def __gt__(self, other) -> bool:
"""Test whether ``self`` implies ``other`` without having same meaning."""
if self == other:
return False
return self >= other
29 changes: 25 additions & 4 deletions authorityspoke/entities.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
"""
Classes representing things that exist in the outside world,
that can be mentioned in legal rules. Not concepts that
derive their meaning from litigation, such as a legal
Fact, an Allegation, a Pleading, etc.
Because of the challenge of describing the significance
of classifying an object as one kind of Entity rather than
another, all of Entity's subclasses might be collapsed into
a single Entity class.
"""

from __future__ import annotations

from typing import Dict, Iterator, Optional
Expand Down Expand Up @@ -74,11 +86,12 @@ def _context_register(
self, other: Factor, comparison
) -> Iterator[Dict[Factor, Factor]]:
"""
Find how ``self``\'s context of can be mapped onto ``other``\'s.
:yields:
possible ways the context of ``self`` can be
mapped onto the context of ``other``.
the only possible way the context of one ``Entity`` can be
mapped onto the context of another.
"""

# If there was a way to compare an Entity to None, should it return {}?
if comparison(self, other):
yield {self: other, other: self}
Expand All @@ -92,16 +105,24 @@ def contradicts(self, other: Factor) -> bool:
return False

@new_context_helper
def new_context(self, context: Dict[Factor, Factor]) -> Entity:
def new_context(self, changes: Dict[Factor, Factor]) -> Entity:
"""
Create new :class:`Factor`, replacing keys of ``changes`` with values.
Assumes no changes are possible because the :func:`new_context_helper`
decorator would have replaced ``self`` if any replacement was available.
"""
return self


class Association(Entity):
"""
An :class:`Entity` representing a set of people such as members or shareholders,
or a business such as a corporation or LLC, but not an unincorporated
business such as a sole proprietorship.
"""


class Human(Entity):
"""
A "natural person" mentioned as an :class:`Entity` in a factor. On the distinction
Expand Down

0 comments on commit a628fcd

Please sign in to comment.