Skip to content

Commit

Permalink
let new_context_helper search through an Opinion
Browse files Browse the repository at this point in the history
Arguably this just moved complexity from posit_holding to new_context_helper, which is called more often.
  • Loading branch information
mscarey committed Aug 10, 2019
1 parent 735fa4a commit f9f4cb0
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 32 deletions.
38 changes: 27 additions & 11 deletions authorityspoke/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,50 @@ def new_context_helper(func: Callable):
indicates the which generic :class:`.Factor`\s within ``factor`` should
be replaced and what they should be replaced with.
:param context_opinion:
a second object that with generic factors that need to be searched
when trying to resolve what a string in the `changes` parameter
refers to.
:returns:
a new :class:`.Factor` object in the new context.
"""

@functools.wraps(func)
def wrapper(
factor: Factor, changes: Optional[Union[Sequence[Factor], Dict[Factor, Factor]]]
factor: Factor,
changes: Optional[Union[Sequence[Factor], Dict[Factor, Factor]]],
context_opinion: Optional[Opinion] = None,
) -> Factor:

if changes is None:
return func(factor, changes)
return factor
if not isinstance(changes, Iterable):
changes = (changes,)
if not isinstance(changes, dict):
generic_factors = factor.generic_factors
if len(generic_factors) != len(changes):
if len(generic_factors) < len(changes):
raise ValueError(
'If the parameter "changes" is not a list of '
+ "replacements for every element of factor.generic_factors, "
+ 'then "changes" must be a dict where each key is a Factor '
+ "to be replaced and each value is the corresponding "
+ "replacement Factor."
f"The iterable {changes} is too long to be interpreted "
+ f"as a list of replacements for the "
+ f"{len(generic_factors)} items of generic_factors."
)
changes = dict(zip(generic_factors, changes))

for context_factor in changes:
if factor.name == context_factor or (
factor.means(context_factor) and factor.name == context_factor.name
):
name_to_seek = changes[context_factor]
if isinstance(name_to_seek, str):
changes[context_factor] = factor.get_factor_by_name(name_to_seek)
if context_opinion and not changes[context_factor]:
changes[context_factor] = context_opinion.get_factor_by_name(
name_to_seek
)
if not changes[context_factor]:
raise ValueError(
f"Unable to find a Factor with the name '{name_to_seek}'"
)

if factor.means(context_factor) and factor.name == context_factor.name:
return changes[context_factor]

return func(factor, changes)
Expand Down
24 changes: 3 additions & 21 deletions authorityspoke/opinions.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def get_factor_by_name(self, name: str) -> Optional[Factor]:
factor = holding.get_factor_by_name(name)
if factor is not None:
return factor
raise ValueError(f'No factor by the name "{name}" was found')
return None

def posit_holding(
self,
Expand All @@ -157,26 +157,8 @@ def posit_holding(
if not isinstance(holding, Holding):
raise TypeError('"holding" must be an object of type Holding.')

# These lines repeat lines in new_context_helper
if isinstance(context, Factor) or isinstance(context, str):
context = context._wrap_with_tuple(context)

# TODO: this should be a separate function.
# It probably already is one somewhere.
if context is not None:
if isinstance(context, dict):
for factor in context:
if isinstance(context[factor], str):
context[factor] = self.get_factor_by_name(context[factor])
else:
new_context: List[Factor] = []
for factor in context:
if isinstance(factor, str):
new_context.append(self.get_factor_by_name(factor))
else:
new_context.append(factor)
context = dict(zip(holding.generic_factors, new_context))
holding = holding.new_context(context)
if context:
holding = holding.new_context(context, context_opinion=self)
self.holdings.append(holding)

if text_links:
Expand Down

0 comments on commit f9f4cb0

Please sign in to comment.