Skip to content

Test Python docstring in markdown files #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import pytest

from fio_planet import snuggs


@pytest.fixture(autouse=True)
def add_snuggs(doctest_namespace):
doctest_namespace["snuggs"] = snuggs
33 changes: 28 additions & 5 deletions docs/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@ includes:
Expressions are evaluated by `fio_planet.features.snuggs.eval()`. Let's look at
some examples using that function.

Note: the outer parentheses are not optional within `snuggs.eval()`.
!!! note

The outer parentheses are not optional within `snuggs.eval()`.

!!! note

`snuggs.eval()` does not use Python's builtin `eval()` but isn't intended
to be a secure computing environment. Expressions which access the
computer's filesystem and create new processes are possible.

## Builtin Python functions

Expand All @@ -28,27 +36,31 @@ Note: the outer parentheses are not optional within `snuggs.eval()`.
```python
>>> snuggs.eval('(bool 0)')
False

```

`range`:

```python
>>> snuggs.eval('(range 1 4)')
range(1, 4)

```

`list`:

```python
>>> snuggs.eval('(list (range 1 4))')
[1, 2, 3]

```

Values can be bound to names for use in expressions.

```python
>>> snuggs.eval('(list (range start stop))', start=0, stop=5)
[0, 1, 2, 3, 4]

```

## Itertools functions
Expand All @@ -58,6 +70,7 @@ Here's an example of using `itertools.repeat()`.
```python
>>> snuggs.eval('(list (repeat "*" times))', times=6)
['*', '*', '*', '*', '*', '*']

```

## Shapely functions
Expand All @@ -67,13 +80,15 @@ Here's an expression that evaluates to a Shapely Point instance.
```python
>>> snuggs.eval('(Point 0 0)')
<POINT (0 0)>

```

The expression below evaluates to a MultiPoint instance.

```python
>>> snuggs.eval('(union (Point 0 0) (Point 1 1))')
<MULTIPOINT (0 0, 1 1)>

```

## Functions specific to fio-planet
Expand All @@ -91,20 +106,23 @@ geometries.
<GEOMETRYCOLLECTION (POINT (0 0), POINT (1 1))>
>>> snuggs.eval('(list (dump (collect (Point 0 0) (Point 1 1))))')
[<POINT (0 0)>, <POINT (1 1)>]

```

The `identity` function returns its single argument.

```python
>>> snuggs.eval('(identity 42)')
42

```

To count the number of vertices in a geometry, use `vertex_count`.

```python
>>> snuggs.eval('(vertex_count (Point 0 0))')
1

```

The `area`, `buffer`, `distance`, `length`, `simplify`, and `set_precision`
Expand All @@ -119,6 +137,7 @@ longitude and latitude degrees, by a given distance in meters.
```python
>>> snuggs.eval('(buffer (Point 0 0) :distance 100)')
<POLYGON ((0.001 0, 0.001 0, 0.001 0, 0.001 0, 0.001 -0.001, 0.001 -0.001, 0...>

```

The `area` and `length` of this polygon have units of square meter and meter.
Expand All @@ -128,13 +147,15 @@ The `area` and `length` of this polygon have units of square meter and meter.
31214.451487413342
>>> snuggs.eval('(length (buffer (Point 0 0) :distance 100))')
627.3096977558143

```

The `distance` between two geometries is in meters.

```python
>>> snuggs.eval('(distance (Point 0 0) (Point 0.1 0.1))')
15995.164946207413

```

A geometry can be simplified to a tolerance value in meters using `simplify`.
Expand All @@ -144,6 +165,7 @@ There are more examples of this function under
```python
>>> snuggs.eval('(simplify (buffer (Point 0 0) :distance 100) :tolerance 100)')
<POLYGON ((0.001 0, 0 -0.001, -0.001 0, 0 0.001, 0.001 0))>

```

The `set_precision` function snaps a geometry to a fixed precision grid with a
Expand All @@ -152,23 +174,24 @@ size in meters.
```python
>>> snuggs.eval('(set_precision (Point 0.001 0.001) :grid_size 500)')
<POINT (0 0)>

```

## Feature and geometry context for expressions

`fio-filter` and `fio-map` evaluate expressions in the context of a GeoJSON
feature and its geometry attribute. These are named `f` and `g`. For example,
here is an expression that tests whether the input feature is within 50 meters
of the given point.
here is an expression that tests whether the input feature is within 62.5
kilometers of the given point.

```lisp
<= (distance g (Point -105.0 39.753056)) 50.0
--8<-- "tests/test_cli.py:filter"
```

`fio-reduce` evaluates expressions in the context of the sequence of all input
geometries, named `c`. For example, this expression dissolves input
geometries using Shapely's `unary_union`.

```lisp
unary_union c
--8<-- "tests/test_cli.py:reduce"
```
3 changes: 3 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ nav:
- "Topics": 'topics'

markdown_extensions:
- pymdownx.inlinehilite
- pymdownx.snippets:
dedent_subsections: True
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extension configuration here

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, maybe this is what I'm missing! I'll have to give this a shot.

- pymdownx.highlight
- pymdownx.superfences
- mkdocs-click
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,4 @@ filterwarnings = [
"ignore:.*pkg_resources is deprecated as an API",
"ignore:.*module \\'sre_constants\\' is deprecated",
]
doctest_optionflags = "NORMALIZE_WHITESPACE"
34 changes: 31 additions & 3 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,22 @@ def test_map_count():
with open("tests/data/trio.seq") as seq:
data = seq.read()

# Define our map arg using a mkdocs snippet.
arg = """
--8<-- [start:map]
centroid (buffer g 1.0)
--8<-- [end:map]
""".splitlines()[
2
].strip()

runner = CliRunner()
result = runner.invoke(
main_group,
["map", "centroid (buffer g 1.0)"],
["map", arg], # "centroid (buffer g 1.0)"],
input=data,
)

assert result.exit_code == 0
assert result.output.count('"type": "Point"') == 3

Expand All @@ -56,8 +66,17 @@ def test_reduce_union():
with open("tests/data/trio.seq") as seq:
data = seq.read()

# Define our reduce command using a mkdocs snippet.
arg = """
--8<-- [start:reduce]
unary_union c
--8<-- [end:reduce]
""".splitlines()[
2
].strip()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevinlacaille I've got some tested CLI snippets! It's a little tortured, I'm working against Python to keep quotes out of the snippet section, but it works!

Screenshot from 2023-05-03 15-38-14


runner = CliRunner()
result = runner.invoke(main_group, ["reduce", "unary_union c"], input=data)
result = runner.invoke(main_group, ["reduce", arg], input=data)
assert result.exit_code == 0
assert result.output.count('"type": "Polygon"') == 1
assert result.output.count('"type": "LineString"') == 1
Expand Down Expand Up @@ -88,10 +107,19 @@ def test_filter():
with open("tests/data/trio.seq") as seq:
data = seq.read()

# Define our reduce command using a mkdocs snippet.
arg = """
--8<-- [start:filter]
< (distance g (Point 4 43)) 62.5E3
--8<-- [end:filter]
""".splitlines()[
2
].strip()

runner = CliRunner()
result = runner.invoke(
main_group,
["filter", "< (distance g (Point 4 43)) 62.5E3"],
["filter", arg],
input=data,
catch_exceptions=False,
)
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ envlist =
deps =
pytest-cov
commands =
python -m pytest -v --cov fio_planet --cov-report term-missing --pdb
python -m pytest -v --cov fio_planet --cov-report term-missing --doctest-glob="*.md"

[gh-actions]
python =
Expand Down