Skip to content

Commit 3968ed8

Browse files
committed
Determined proper use of conditional import; revert type annotations to classes from module addresses
Update tox.ini Build docs on 3.9 via readthedocs/readthedocs.org#7554 (comment) Update __init__.py Give intersphinx internal package name (ranges) Use intersphinx to link to external package typo Remove non-functional intersphinx aliases Revert to working python-ranges link
1 parent 277dad6 commit 3968ed8

File tree

8 files changed

+43
-32
lines changed

8 files changed

+43
-32
lines changed

.readthedocs.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
version: 2
44
sphinx:
55
configuration: docs/conf.py
6+
build:
7+
image: testing
68
python:
7-
version: 3.8
9+
version: 3.9
810

911
install:
1012
- method: pip

docs/conf.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@
4444

4545
intersphinx_mapping = {
4646
"python": ("https://docs.python.org/3/", None),
47-
"python-ranges": ("https://python-ranges.readthedocs.io/en/latest/", None),
48-
# "httpx": ("https://www.python-httpx.org/", None),
47+
"ranges": ("https://python-ranges.readthedocs.io/en/latest/", None),
4948
}
5049

5150
suppress_warnings = [

src/range_streams/__init__.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
r"""
22
:mod:`range_streams` provides file-like object handling through
33
an API familiar to users of the standard library
4-
:mod:`io` module. It uses Range, RangeSet, and RangeDict classes
4+
:mod:`io` module. It uses :class:`ranges.Range`, :class:`ranges.RangeSet`,
5+
and :class:`ranges.RangeDict` classes (from the externally maintained
6+
`python-ranges <https://python-ranges.readthedocs.io/en/latest/>`_ library)
57
to represent and look up range operations in an efficient linked
6-
list data structure from the externally maintained python-ranges
7-
library.
8+
list data structure.
89
910
Servers with support for `HTTP range requests
1011
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests>`_

src/range_streams/http_utils.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
from __future__ import annotations
22

3-
import ranges
3+
from typing import TYPE_CHECKING
4+
5+
from ranges import Range
6+
7+
if TYPE_CHECKING:
8+
import ranges
49

510
from .range_utils import range_termini
611

712
__all__ = ["byte_range_from_range_obj", "range_header"]
813

914

10-
def byte_range_from_range_obj(rng: ranges.Range) -> str:
15+
def byte_range_from_range_obj(rng: Range) -> str:
1116
"""Prepare the byte range substring for a HTTP `range request
1217
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests>`_.
1318
@@ -22,7 +27,7 @@ def byte_range_from_range_obj(rng: ranges.Range) -> str:
2227
return byte_range
2328

2429

25-
def range_header(rng: ranges.Range) -> dict[str, str]:
30+
def range_header(rng: Range) -> dict[str, str]:
2631
"""Prepare a :class:`dict` to pass as a :mod:`httpx` request header
2732
with a single key ``ranges`` whose value is the byte range.
2833

src/range_streams/overlaps.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import TYPE_CHECKING
44

55
import ranges
6-
from ranges import Range
6+
from ranges import Range, RangeDict
77

88
# due to https://github.com/agronholm/sphinx-autodoc-typehints/issues/72
99
import range_streams # for RangeStream
@@ -19,7 +19,7 @@
1919

2020
# This could be written more clearly by using a range_utils helper function shared with
2121
# most_recent_range
22-
def get_range_containing(rng_dict: ranges.RangeDict, position: int) -> ranges.Range:
22+
def get_range_containing(rng_dict: RangeDict, position: int) -> Range:
2323
"""Get a :class:`ranges.Range` from ``rng_dict`` by looking up the ``position`` it
2424
contains, where ``rng_dict`` is either the internal :obj:`RangeStream._ranges`
2525
or the external :obj:`RangeStream.ranges`.
@@ -42,7 +42,7 @@ def get_range_containing(rng_dict: ranges.RangeDict, position: int) -> ranges.Ra
4242

4343

4444
def burn_range(
45-
stream: range_streams.range_stream.RangeStream, overlapped_ext_rng: ranges.Range
45+
stream: range_streams.range_stream.RangeStream, overlapped_ext_rng: Range
4646
):
4747
internal_rng = ext2int(stream=stream, ext_rng=overlapped_ext_rng)
4848
stream._ranges.remove(internal_rng)
@@ -52,7 +52,7 @@ def burn_range(
5252

5353
def handle_overlap(
5454
stream: range_streams.range_stream.RangeStream,
55-
rng: ranges.Range,
55+
rng: Range,
5656
internal: bool = False,
5757
) -> None:
5858
"""
@@ -118,7 +118,7 @@ def handle_overlap(
118118

119119
def overlap_whence(
120120
stream: range_streams.range_stream.RangeStream,
121-
rng: ranges.Range,
121+
rng: Range,
122122
internal: bool = False,
123123
) -> int | None:
124124
"""

src/range_streams/range_request.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
from typing import TYPE_CHECKING, Iterator
44

55
import httpx
6-
import ranges
6+
from ranges import Range
7+
8+
if TYPE_CHECKING:
9+
import ranges
710

811
from .http_utils import range_header
912

@@ -18,7 +21,7 @@ class RangeRequest:
1821
suitable for `RangeResponse` to wrap in a `io.BytesIO` buffered stream.
1922
"""
2023

21-
def __init__(self, byte_range: ranges.Range, url: str, client: httpx.Client):
24+
def __init__(self, byte_range: Range, url: str, client: httpx.Client):
2225
self.range = byte_range
2326
self.url = url
2427
self.client = client

src/range_streams/range_utils.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,26 @@
1212

1313
from typing import TYPE_CHECKING
1414

15-
import ranges
16-
from ranges import Range
15+
if TYPE_CHECKING:
16+
import ranges
17+
from ranges import Range, RangeDict
1718

1819
import range_streams
1920

2021

21-
def ranges_in_reg_order(ranges: ranges.RangeDict) -> list[Range]:
22+
def ranges_in_reg_order(ranges: RangeDict) -> list[Range]:
2223
"Presumes integrity is already checked: ranges in order of registration"
2324
return [k[0].ranges()[0] for k, v in ranges.items()]
2425

2526

26-
def response_ranges_in_reg_order(ranges: ranges.RangeDict) -> list[Range]:
27+
def response_ranges_in_reg_order(ranges: RangeDict) -> list[Range]:
2728
"RangeResponse requested ranges in order of registration"
2829
return [v.request.range for k, v in ranges.items()]
2930

3031

3132
def most_recent_range(
3233
stream: range_streams.range_stream.RangeStream, internal: bool = True
33-
) -> ranges.Range | None:
34+
) -> Range | None:
3435
if stream._ranges.isempty():
3536
rng = None # type: Range | None
3637
else:
@@ -39,7 +40,7 @@ def most_recent_range(
3940
return rng
4041

4142

42-
def range_termini(rng: ranges.Range) -> tuple[int, int]:
43+
def range_termini(rng: Range) -> tuple[int, int]:
4344
"""
4445
Get the inclusive start and end positions `[start,end]` from a `ranges.Range`.
4546
These are referred to as the 'termini'. Ranges are always ascending.
@@ -52,26 +53,26 @@ def range_termini(rng: ranges.Range) -> tuple[int, int]:
5253
return start, end
5354

5455

55-
def range_len(rng: ranges.Range) -> int:
56+
def range_len(rng: Range) -> int:
5657
rmin, rmax = range_termini(rng)
5758
return rmax - rmin
5859

5960

60-
def range_min(rng: ranges.Range) -> int:
61+
def range_min(rng: Range) -> int:
6162
if rng.isempty():
6263
raise ValueError("Empty range has no minimum")
6364
return range_termini(rng)[0]
6465

6566

66-
def range_max(rng: ranges.Range) -> int:
67+
def range_max(rng: Range) -> int:
6768
if rng.isempty():
6869
raise ValueError("Empty range has no maximum")
6970
return range_termini(rng)[1]
7071

7172

7273
def validate_range(
73-
byte_range: ranges.Range | tuple[int, int], allow_empty: bool = True
74-
) -> ranges.Range:
74+
byte_range: Range | tuple[int, int], allow_empty: bool = True
75+
) -> Range:
7576
"""
7677
Validate byte_range and convert to `[a,b)` :class:`ranges.Range` if given as integer
7778
tuple.
@@ -95,7 +96,7 @@ def validate_range(
9596
return byte_range
9697

9798

98-
def range_span(ranges: list[ranges.Range]) -> ranges.Range:
99+
def range_span(ranges: list[Range]) -> Range:
99100
"""
100101
Assumes input list of :class:`RangeSets` are in ascending order, switches if not
101102
"""
@@ -109,7 +110,7 @@ def range_span(ranges: list[ranges.Range]) -> ranges.Range:
109110

110111

111112
def ext2int(
112-
stream: range_streams.range_stream.RangeStream, ext_rng: ranges.Range
113+
stream: range_streams.range_stream.RangeStream, ext_rng: Range
113114
) -> range_streams.range_stream.RangeResponse:
114115
"""
115116
Given the external range `ext_rng` and the :class:`RangeStream` ``stream`` on which it is

tox.ini

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ testpaths = tests
44

55
[gh-actions]
66
python =
7-
3.8: py38, mypy, lint, docs
8-
3.9: py39
7+
3.8: py38, mypy, lint
8+
3.9: py39, docs
99

1010
[tox]
1111
envlist = lint, mypy, {py38,py39}, docs, coverage-report
@@ -35,7 +35,7 @@ commands = mypy src
3535

3636
[testenv:docs]
3737
description = Build docs and run doctests.
38-
basepython = python3.8
38+
basepython = python3.9
3939
extras = docs
4040
changedir = docs
4141
commands =

0 commit comments

Comments
 (0)