| """Functions brought over from jaraco.text. |
| |
| These functions are not supposed to be used within `pip._internal`. These are |
| helper functions brought over from `jaraco.text` to enable vendoring newer |
| copies of `pkg_resources` without having to vendor `jaraco.text` and its entire |
| dependency cone; something that our vendoring setup is not currently capable of |
| handling. |
| |
| License reproduced from original source below: |
| |
| Copyright Jason R. Coombs |
| |
| Permission is hereby granted, free of charge, to any person obtaining a copy |
| of this software and associated documentation files (the "Software"), to |
| deal in the Software without restriction, including without limitation the |
| rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
| sell copies of the Software, and to permit persons to whom the Software is |
| furnished to do so, subject to the following conditions: |
| |
| The above copyright notice and this permission notice shall be included in |
| all copies or substantial portions of the Software. |
| |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| IN THE SOFTWARE. |
| """ |
| |
| import functools |
| import itertools |
| |
| |
| def _nonblank(str): |
| return str and not str.startswith("#") |
| |
| |
| @functools.singledispatch |
| def yield_lines(iterable): |
| r""" |
| Yield valid lines of a string or iterable. |
| |
| >>> list(yield_lines('')) |
| [] |
| >>> list(yield_lines(['foo', 'bar'])) |
| ['foo', 'bar'] |
| >>> list(yield_lines('foo\nbar')) |
| ['foo', 'bar'] |
| >>> list(yield_lines('\nfoo\n#bar\nbaz #comment')) |
| ['foo', 'baz #comment'] |
| >>> list(yield_lines(['foo\nbar', 'baz', 'bing\n\n\n'])) |
| ['foo', 'bar', 'baz', 'bing'] |
| """ |
| return itertools.chain.from_iterable(map(yield_lines, iterable)) |
| |
| |
| @yield_lines.register(str) |
| def _(text): |
| return filter(_nonblank, map(str.strip, text.splitlines())) |
| |
| |
| def drop_comment(line): |
| """ |
| Drop comments. |
| |
| >>> drop_comment('foo # bar') |
| 'foo' |
| |
| A hash without a space may be in a URL. |
| |
| >>> drop_comment('http://example.com/foo#bar') |
| 'http://example.com/foo#bar' |
| """ |
| return line.partition(" #")[0] |
| |
| |
| def join_continuation(lines): |
| r""" |
| Join lines continued by a trailing backslash. |
| |
| >>> list(join_continuation(['foo \\', 'bar', 'baz'])) |
| ['foobar', 'baz'] |
| >>> list(join_continuation(['foo \\', 'bar', 'baz'])) |
| ['foobar', 'baz'] |
| >>> list(join_continuation(['foo \\', 'bar \\', 'baz'])) |
| ['foobarbaz'] |
| |
| Not sure why, but... |
| The character preceeding the backslash is also elided. |
| |
| >>> list(join_continuation(['goo\\', 'dly'])) |
| ['godly'] |
| |
| A terrible idea, but... |
| If no line is available to continue, suppress the lines. |
| |
| >>> list(join_continuation(['foo', 'bar\\', 'baz\\'])) |
| ['foo'] |
| """ |
| lines = iter(lines) |
| for item in lines: |
| while item.endswith("\\"): |
| try: |
| item = item[:-2].strip() + next(lines) |
| except StopIteration: |
| return |
| yield item |