Skip to content

Commit

Permalink
feat: remove unneeded refs, use xloop.
Browse files Browse the repository at this point in the history
  • Loading branch information
joshorr committed Apr 5, 2023
1 parent 40ad409 commit ee74341
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 39 deletions.
14 changes: 13 additions & 1 deletion poetry.lock

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

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ repository = "https://github.com/xyngular/py-xurls"
[tool.poetry.dependencies]
python = "^3.8"
xsentinels = "^1.2.1"
xloop = "^1.0.1"

[tool.poetry.dev-dependencies]
ipdb = "^0.13.9"
Expand Down
52 changes: 14 additions & 38 deletions xurls/url.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@
a query value. For now, it's only for the path.
Here is an example:
`"http://api.xyngular.com/v1/accounts/{id}"`
`"http://api.com/v1/accounts/{id}"`
If later on, we add a query like this to the URL:
`URLMutable.query_add`('id', 1)
And then call `url.url()`, we will get back this:
`"http://api.xyngular.com/v1/accounts/1"`
`"http://api.com/v1/accounts/1"`
You can also pass in a secondary/backup list of key/values into the .url(...) method,
like so:
>>> url = URL("https://api.xyngular.com/some/endpoint/{id}")
>>> url = URL("https://api.com/some/endpoint/{id}")
>>> url.url(secondary_values={'id': 9})
"https://api.xyngular.com/some/endpoint/9"
"https://api.com/some/endpoint/9"
It can also be an object, which in this case it will look for an attribute of `id`.
Expand Down Expand Up @@ -76,6 +76,7 @@
from types import MappingProxyType
from dataclasses import dataclass
import string
from xloop import xloop

# I'm not going to worry about url 'parameters' for now,
# URL parameter example: "http://www.google.com/some_path;paramA=value1;paramB=value2"
Expand Down Expand Up @@ -104,8 +105,8 @@ class _FormattedQueryValue:
already have that suffix.
.. note:: Thinking about putting in an ability to change the default formatter via a
`xynlib.context.Resource`. That way it could easily be overridden via a
`xynlib.context.Context`. I'll do that if/when we need it.
`xinject.context.Resource`. That way it could easily be overridden via a
`xinject.context.Context`. I'll do that if/when we need it.
For now the default _FormattedQueryValue is just a plain instance that is shared
via a private module attribute.
"""
Expand Down Expand Up @@ -432,7 +433,7 @@ def __init__(
any that were provided in `url` string. Same goes with the 'path'.
Use 'append_url(...)' to easily merge/append query/paths together.
If `xynlib.types.Default` is left in place, then that value will be ignored and not replace
If `xsentinels.Default` is left in place, then that value will be ignored and not replace
anything that was parsed for that component from `url` string. Unless the 'url'
pass in defined that particular component it will be set to None. When you append
a URL on another with values set to None, it will not 'append' them into the URL.
Expand Down Expand Up @@ -915,7 +916,7 @@ def _parse_string_into_query(self, query_string: str) -> Query:

existing_value = query.get(k)
if existing_value:
all_values.extend(_loop(existing_value))
all_values.extend(xloop(existing_value))

if force_list or len(all_values) > 1:
query[k] = all_values
Expand All @@ -931,7 +932,7 @@ def _format_query_into_string(self, query: Query) -> str:
options = self.formatting_options or DefaultQueryValueListFormat
query_filtered = {}
for key, val in query.items():
values = list(_loop(val))
values = list(xloop(val))

if not values:
continue
Expand Down Expand Up @@ -961,7 +962,7 @@ def _formatted_map(
that support multiple objects. It's just not needed right now. But the interface
allows for it in the future, when we get around to support it.
If left as `xynlib.types.Default` then we will use self.secondary_values,
If left as `xsentinels.Default` then we will use self.secondary_values,
if any are there. You can 'attach' secondary values to a URL via:
>>> URLMutable.is_valid(secondary_values={'id': 2}, attach_values=True)
Expand Down Expand Up @@ -994,7 +995,7 @@ def _formatted_map(
# TODO: ********

if not isinstance(query_value, str):
query_value = list(_loop(query_value))
query_value = list(xloop(query_value))

if len(query_value) == 1:
query_value = query_value[0]
Expand All @@ -1015,7 +1016,7 @@ def _formatted_map(
elif isinstance(secondary_values, dict):
obj_value = secondary_values.get(k)
else:
all_objs = list(_loop(secondary_values))
all_objs = list(xloop(secondary_values))
if len(all_objs) == 1 and hasattr(all_objs[0], k):
obj_value = getattr(all_objs[0], k)
else:
Expand Down Expand Up @@ -1284,7 +1285,7 @@ def set_methods(self, methods: Union[Iterable[str], str], *args):
`self` is returned, so you can chain this with other method calls.
"""
self._set_methods(_loop(methods, args))
self._set_methods(xloop(methods, args))
return self

def set_singular(self, value: Optional[bool]) -> URLMutable:
Expand Down Expand Up @@ -1423,31 +1424,6 @@ def query_remove(self, key) -> URLMutable:
return self


def _loop(*args: Union[Iterable[T], T]) -> Iterator[T]:
"""
Copied from xynlib.generators.loop to here to eliminate the dependency
"""
# Reminder: 'anything' is all positional arguments passed into method.
if not args:
return

yield_for = (str, int, bytes, dict)

for arg in args:
if arg is None:
continue
if isinstance(arg, yield_for):
yield arg
continue
try:
arg_iter = iter(arg)
except TypeError:
yield arg
else:
for item in arg_iter:
yield item


# Basically, we have to set every attribute except query/path/methods.
# For path we can append to the end of it.
# For query, we can merge them together since they are Dict's.
Expand Down

0 comments on commit ee74341

Please sign in to comment.