diff --git a/poetry.lock b/poetry.lock index e50b3ea..473893e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1033,6 +1033,18 @@ files = [ {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, ] +[[package]] +name = "xloop" +version = "1.0.1" +description = "General purpose for/iterator looping generators/utilities." +category = "main" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "xloop-1.0.1-py3-none-any.whl", hash = "sha256:e24aa87d664d5985c8ad7cdeecbc91313066ea3f1894cead9719b011362da6eb"}, + {file = "xloop-1.0.1.tar.gz", hash = "sha256:bb639738edfcaa8d8fe89befaab7eae5f53caa7cef5ac5c836f3545de60dcd28"}, +] + [[package]] name = "xsentinels" version = "1.2.1" @@ -1067,4 +1079,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "8cd4856bc28acc589c5ef73160ef2afd657e55721ab2b35edafb3b183fbb61e2" +content-hash = "de96d95296ce7088380b26d3b3a641b41f6a980ad0cb817e7c71bde064fec673" diff --git a/pyproject.toml b/pyproject.toml index 6e50c0c..6c6b339 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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" diff --git a/xurls/url.py b/xurls/url.py index 211ec38..5e873fe 100644 --- a/xurls/url.py +++ b/xurls/url.py @@ -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`. @@ -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" @@ -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. """ @@ -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. @@ -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 @@ -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 @@ -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) @@ -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] @@ -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: @@ -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: @@ -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.