Skip to content

Commit 4917e50

Browse files
redo docs with mkdocs (#14)
* redo docs with mkdocs * fix ci * pin slap-cli version * fix ci * replace banner with logo (chatgpt ftw) * unpin slap version * update * get rid of changelog.sh * only deploy pages on develop * update renovate.json
1 parent be1a707 commit 4917e50

File tree

11 files changed

+187
-151
lines changed

11 files changed

+187
-151
lines changed

.github/workflows/docs.yaml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Documentation
2+
3+
on:
4+
push:
5+
branches: [ "develop" ]
6+
tags: [ "*" ]
7+
pull_request:
8+
branches: [ "develop" ]
9+
10+
jobs:
11+
docs:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: NiklasRosenstein/slap@gha/install/v1
16+
- run: slap install --only-extras docs --no-venv-check
17+
- run: slap run --no-venv-check docs:build
18+
- uses: actions/upload-artifact@v4
19+
with:
20+
name: docs
21+
path: docs/_site
22+
23+
docs-publish:
24+
needs: [ docs ]
25+
runs-on: ubuntu-latest
26+
if: github.ref == 'refs/heads/develop'
27+
steps:
28+
- uses: actions/checkout@v2
29+
- uses: actions/download-artifact@v2
30+
with: { name: docs, path: docs/site }
31+
- uses: JamesIves/[email protected]
32+
with: { branch: gh-pages, folder: docs/site, ssh-key: "${{ secrets.DEPLOY_KEY }}" }

.github/workflows/python.yml

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,3 @@ jobs:
3737
if: ${{ !startsWith(matrix.python-version, '3.12.') && matrix.python-version != '3.x' }}
3838
- run: slap test pytest
3939
if: ${{ startsWith(matrix.python-version, '3.12.') || matrix.python-version == '3.x' }}
40-
41-
docs:
42-
runs-on: ubuntu-latest
43-
steps:
44-
- uses: actions/checkout@v4
45-
- uses: NiklasRosenstein/slap@gha/install/v1
46-
- run: slap install --only-extras docs --no-venv-check
47-
- run: slap run --no-venv-check docs:build
48-
- uses: actions/upload-artifact@v4
49-
with:
50-
name: docs
51-
path: docs/_site
52-
53-
docs-publish:
54-
needs: [ test, docs ]
55-
runs-on: ubuntu-latest
56-
steps:
57-
- uses: actions/checkout@v4
58-
- uses: actions/download-artifact@v4
59-
with: { name: docs, path: docs/_site }
60-
- uses: JamesIves/[email protected]
61-
with: { branch: gh-pages, folder: docs/_site, ssh-key: "${{ secrets.DEPLOY_KEY }}" }

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/.vscode
22
/dist
33
/build
4-
.venv/
4+
.venv*/
55
*.egg-info/
66
__pycache__/
77
poetry.lock

README.md

Lines changed: 8 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,132 +1,15 @@
1-
# typeapi
1+
<p align="center"><img src="https://i.imgur.com/11FvXpa.png"></p>
22

3-
[![Python](https://github.com/NiklasRosenstein/python-typeapi/actions/workflows/python.yml/badge.svg)](https://github.com/NiklasRosenstein/python-typeapi/actions/workflows/python.yml)
3+
<h1 align="center">python-typeapi</h1>
44

5-
[PEP484]: https://peps.python.org/pep-0484/
65
[PEP585]: https://peps.python.org/pep-0585/
76
[PEP604]: https://peps.python.org/pep-0604/
7+
[documentation]: https://niklasrosenstein.github.io/python-typeapi/
88

9-
__Compatibility__: Python 3.8+
9+
The `typeapi` package provides a **unified and consistent** API for the reflection Python type hints from
10+
CPython 3.6.3 onwards. It also allows evaluating string-literal type annotations of more recent Python releases in
11+
older versions (such as [PEP585][] and [PEP604][] expressions).
1012

11-
The `typeapi` package provides an object-oriented interface for introspecting [PEP484][] type hints at runtime,
12-
including forward references that make use of the more recent [PEP585][] and [PEP604][] type hint features in
13-
Python versions that don't natively support them.
13+
To learn more about this package, visit its [documentation][].
1414

15-
The main API of this module is comprised of:
16-
17-
* `typeapi.TypeHint()` &ndash; A class to parse low-level type hints and present them in a consistent, object-oriented API.
18-
* `typeapi.get_annotations()` &ndash; Retrieve an object's `__annotations__` with support for evaluating future type hints ([PEP585][], [PEP604][]).
19-
20-
The following kinds of type hints are currently supported:
21-
22-
| Concrete type | Description | Added in |
23-
|----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|
24-
| `ClassTypeHint` | For any normal or generic type as well as `typing.Any`. Provides access to the underlying type, the type arguments and parameters, if any. | 1.0.0 |
25-
| `UnionTypeHint` | Represents `Union` type hint and gives access to the union members. | 1.0.0 |
26-
| `LiteralTypeHint` | Represents a `Literal` type hint and gives access to the literal values. | 1.0.0 |
27-
| `AnnotatedTypeHint` | Represents an `Annotated` type hint and gives access to the annotated type as well as the metadata. | 1.0.0 |
28-
| `TypeVarTypeHint` | Represents a `TypeVar` type hint and gives an interface to access the variable's metadata (such as constarints, variance, ...). | 1.0.0 |
29-
| `ForwardRefTypeHint` | Represents a forward reference. Can be evaluated in Python 3.6+ even if it contains [PEP585][] (3.9+) and [PEP604][] (3.10+) expressions. <sup>1)</sup> | 1.0.0, future support in 1.3.0 |
30-
| `TupleTypeHint` | Reperesents a `Tuple` type hint, allowing you to differentiate between repeated and explicitly sized tuples. | 1.2.0 |
31-
32-
<sup>1)</sup> New-style type union evaluation will continue to return a `typing.Union`, even if the same syntax
33-
evaluated natively by Python 3.10+ results in a `types.UnionType`.
34-
35-
## Examples
36-
37-
Inspect a `List[int]` type hint:
38-
39-
```py
40-
# cat <<EOF | python -
41-
from typeapi import ClassTypeHint, TypeHint
42-
from typing import List
43-
44-
hint = TypeHint(List[int])
45-
assert isinstance(hint, ClassTypeHint)
46-
assert hint.type is list
47-
48-
item_hint = hint[0]
49-
assert isinstance(item_hint, ClassTypeHint)
50-
assert item_hint.type is int
51-
```
52-
53-
Retrieve the metadata from an `Annotated[...]` type hint:
54-
55-
```py
56-
# cat <<EOF | python -
57-
from typeapi import AnnotatedTypeHint, ClassTypeHint, TypeHint
58-
from typing_extensions import Annotated
59-
60-
hint = TypeHint(Annotated[int, 42])
61-
assert isinstance(hint, AnnotatedTypeHint)
62-
assert hint.type is int
63-
assert hint.metadata == (42,)
64-
65-
sub_hint = hint[0]
66-
assert isinstance(sub_hint, ClassTypeHint)
67-
assert sub_hint.type is int
68-
```
69-
70-
Parameterize one type hint with the parameterization of a generic alias:
71-
72-
```py
73-
# cat <<EOF | python -
74-
from dataclasses import dataclass
75-
from typeapi import ClassTypeHint, TypeHint
76-
from typing import Generic, TypeVar
77-
from typing_extensions import Annotated
78-
79-
T = TypeVar("T")
80-
81-
@dataclass
82-
class MyGeneric(Generic[T]):
83-
value: T
84-
85-
hint = TypeHint(MyGeneric[int])
86-
assert isinstance(hint, ClassTypeHint)
87-
assert hint.get_parameter_map() == {T: int}
88-
89-
member_hint = TypeHint(T).parameterize(hint.get_parameter_map())
90-
assert isinstance(member_hint, ClassTypeHint)
91-
assert member_hint.type is int
92-
```
93-
94-
Evaluate forward references with `get_annotations()`:
95-
96-
```py
97-
# cat <<EOF | python -
98-
from typeapi import get_annotations
99-
from typing import Optional
100-
from sys import version_info
101-
102-
class MyType:
103-
a: "str | None"
104-
105-
annotations = get_annotations(MyType)
106-
107-
if version_info[:2] < (3, 10):
108-
assert annotations == {"a": Optional[str]}
109-
else:
110-
assert annotations == {"a": str | None}
111-
```
112-
113-
Evaluating forward references with the `TypeHint` API:
114-
115-
```py
116-
# cat <<EOF | python -
117-
from typeapi import ClassTypeHint, ForwardRefTypeHint, TypeHint
118-
119-
MyVector = "list[MyType]"
120-
121-
class MyType:
122-
pass
123-
124-
hint = TypeHint(MyVector).evaluate(globals())
125-
print(hint) # TypeHint(typing.List[__main__.MyType])
126-
assert isinstance(hint, ClassTypeHint)
127-
assert hint.type is list
128-
129-
item_hint = hint[0]
130-
assert isinstance(item_hint, ClassTypeHint)
131-
assert item_hint.type is MyType
132-
```
15+
Please file bug reports and feature requests [on GitHub](https://github.com/NiklasRosenstein/python-typeapi/issues).

docs/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
changelog.md
2+
/site

docs/docs/api/typeapi.utils.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

docs/docs/assets/typeapi-256.png

59.2 KB
Loading

docs/docs/examples.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Examples
2+
3+
#### Inspect a `List[int]` type hint
4+
5+
```py
6+
from typeapi import ClassTypeHint, TypeHint
7+
from typing import List
8+
9+
hint = TypeHint(List[int])
10+
assert isinstance(hint, ClassTypeHint)
11+
assert hint.type is list
12+
13+
item_hint = hint[0]
14+
assert isinstance(item_hint, ClassTypeHint)
15+
assert item_hint.type is int
16+
```
17+
18+
#### Retrieve the metadata from an `Annotated[...]` type hint
19+
20+
```py
21+
from typeapi import AnnotatedTypeHint, ClassTypeHint, TypeHint
22+
from typing_extensions import Annotated
23+
24+
hint = TypeHint(Annotated[int, 42])
25+
assert isinstance(hint, AnnotatedTypeHint)
26+
assert hint.type is int
27+
assert hint.metadata == (42,)
28+
29+
sub_hint = hint[0]
30+
assert isinstance(sub_hint, ClassTypeHint)
31+
assert sub_hint.type is int
32+
```
33+
34+
#### Parameterize one type hint with the parameterization of a generic alias
35+
36+
```py
37+
from dataclasses import dataclass
38+
from typeapi import ClassTypeHint, TypeHint
39+
from typing import Generic, TypeVar
40+
from typing_extensions import Annotated
41+
42+
T = TypeVar("T")
43+
44+
@dataclass
45+
class MyGeneric(Generic[T]):
46+
value: T
47+
48+
hint = TypeHint(MyGeneric[int])
49+
assert isinstance(hint, ClassTypeHint)
50+
assert hint.get_parameter_map() == {T: int}
51+
52+
member_hint = TypeHint(T).parameterize(hint.get_parameter_map())
53+
assert isinstance(member_hint, ClassTypeHint)
54+
assert member_hint.type is int
55+
```
56+
57+
#### Evaluate forward references with `get_annotations()`
58+
59+
```py
60+
from typeapi import get_annotations
61+
from typing import Optional
62+
from sys import version_info
63+
64+
class MyType:
65+
a: "str | None"
66+
67+
annotations = get_annotations(MyType)
68+
69+
if version_info[:2] < (3, 10):
70+
assert annotations == {"a": Optional[str]}
71+
else:
72+
assert annotations == {"a": str | None}
73+
```
74+
75+
#### Evaluating forward references with the `TypeHint` API
76+
77+
```py
78+
from typeapi import ClassTypeHint, ForwardRefTypeHint, TypeHint
79+
80+
MyVector = "list[MyType]"
81+
82+
class MyType:
83+
pass
84+
85+
hint = TypeHint(MyVector).evaluate(globals())
86+
print(hint) # TypeHint(typing.List[__main__.MyType])
87+
assert isinstance(hint, ClassTypeHint)
88+
assert hint.type is list
89+
90+
item_hint = hint[0]
91+
assert isinstance(item_hint, ClassTypeHint)
92+
assert item_hint.type is MyType
93+
```

docs/docs/features.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Supported Features
2+
3+
This page documents all features of the Python type annotation ecosystem that are supported by the `typeapi` package.
4+
5+
[PEP484]: https://peps.python.org/pep-0484/
6+
[PEP526]: https://peps.python.org/pep-0526/
7+
[PEP585]: https://peps.python.org/pep-0585/
8+
[PEP586]: https://peps.python.org/pep-0586/
9+
[PEP593]: https://peps.python.org/pep-0593/
10+
[PEP604]: https://peps.python.org/pep-0604/
11+
[PEP646]: https://peps.python.org/pep-0646/
12+
[PEP695]: https://peps.python.org/pep-0695/
13+
14+
| Feature | Supported since | Example | Implemented via | Related PEPs |
15+
|--------------------------------------|-----------------|--------------------------------------|-------------------------------------------------------------|----------------------------------------------|
16+
| Normal type hint | 1.0.0 | `int`, `MyType`, `list[str]` | [`ClassTypeHint`](./api/typeapi.md#typeapi.ClassTypeHint) | [PEP484][], [PEP526][] |
17+
| Generics in standard collection [^4] | 1.3.0 | `list[int]`, `dict[str, str]` | [`ClassTypeHint`](./api/typeapi.md#typeapi.ClassTypeHint) | [PEP585][] |
18+
| Tuples | 1.0.0 | `tuple[int, str]`, `Tuple[Any, ...]` | [`TupleTypeHint`](./api/typeapi.md#typeapi.TupleTypeHint) | [PEP484][] |
19+
| Union types | 1.0.0 | `Union[int, str]`, `int \| str` | [`UnionTypeHint`](./api/typeapi.md#typeapi.UnionTypeHint) | [PEP484][], [PEP604][] |
20+
| Sugar syntax for union types [^5] | 1.3.0 | `int \| str` | [`UnionTypeHint`](./api/typeapi.md#typeapi.UnionTypeHint) | [PEP604][] |
21+
| Literals | 1.0.0 | `Literal["a", 42]` | [`LiteralTypeHint`](./api/typeapi.md#typeapi.LiteralTypeHint) | [PEP586][] |
22+
| Annotated | 1.0.0 | `Annotated[int, "hello_world"]` | [`AnnotatedTypeHint`](./api/typeapi.md#typeapi.AnnotatedTypeHint) | [PEP484][], [PEP593][] |
23+
| Type variables | 1.0.0 | `TypeVar("T")` | [`TypeVarTypeHint`](./api/typeapi.md#typeapi.TypeVarTypeHint) | [PEP484][], [PEP646][] [^2], [PEP695][] [^3] |
24+
| Forward references | 1.0.0 | `"MyType"` | [`ForwardRefTypeHint`](./api/typeapi.md#typeapi.ForwardRefTypeHint) | [PEP484][] |
25+
26+
[^2]: [PEP646 - Variadic Generics][PEP646] is not currently officially supported. Reflecting type hints using this
27+
language feature may fail.
28+
29+
[^3]: [PEP695 - Type Parameter Syntax][PEP695] is not currently officially supported. Reflecting type hints using this
30+
language feature may fail.
31+
32+
[^4]: Forward references may use the generic syntax introduced in [PEP585 - Type Hinting Generics In Standard Collections][PEP585]
33+
in older Python (< 3.9) versions that do not implement this PEP. `typeapi` will evaluate the forward reference accordingly and
34+
return the correct parameterized generic type hint from the `typing` module.
35+
36+
[^5]: The union syntax introduced by [PEP 604 - Allow writing union types as `X | Y`][PEP604] may be used in older Python
37+
versions (< 3.10) via forward references. `typeapi` will evaluate the forward reference accordingly and return the corresponding
38+
`typing.Union` type hint. Note that the evaluation of new-style union types from string literals will always return a
39+
`typing.Union` despite the same syntax evaluated in Python versions supporting the syntax returning `types.UnionType`
40+
instead.

docs/mkdocs.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ markdown_extensions:
4444

4545
nav:
4646
- Home: index.md
47+
- features.md
48+
- examples.md
4749
- API:
4850
- typeapi: api/typeapi.md
49-
- typeapi.utils: api/typeapi.utils.md
5051
- Other:
5152
- Changelog: changelog.md

0 commit comments

Comments
 (0)