diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffc29ad..c486556 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -152,9 +152,8 @@ jobs: run: pdm run make docs - name: Save PR number - env: - PR_NUMBER: ${{ github.event.number }} - run: echo $PR_NUMBER > .pr_number + run: | + echo "${{ github.event.number }}" > .pr_number - name: Upload artifact uses: actions/upload-artifact@v3 diff --git a/.github/workflows/docs-preview.yml b/.github/workflows/docs-preview.yml index 5fdd985..5c30fef 100644 --- a/.github/workflows/docs-preview.yml +++ b/.github/workflows/docs-preview.yml @@ -29,8 +29,14 @@ jobs: path: docs-preview name: docs-preview - - name: Set PR number - run: echo "PR_NUMBER=$(cat docs-preview/.pr_number)" >> $GITHUB_ENV + - name: Validate and set PR number + run: | + PR_NUMBER=$(cat docs-preview/.pr_number) + if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then + echo "Invalid PR number: $PR_NUMBER" + exit 1 + fi + echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV - name: Deploy docs preview uses: JamesIves/github-pages-deploy-action@v4 diff --git a/pyproject.toml b/pyproject.toml index 09d5e4d..cf8f1cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ classifiers = [ "Intended Audience :: Developers", ] name = "type-lens" -version = "0.2.2" +version = "0.2.3" description = "type-lens is a Python template project designed to simplify the setup of a new project." readme = "README.md" license = { text = "MIT" } diff --git a/tests/test_callable_view.py b/tests/test_callable_view.py index 5804f75..0b67ba9 100644 --- a/tests/test_callable_view.py +++ b/tests/test_callable_view.py @@ -47,7 +47,7 @@ def fn(foo): # type: ignore[no-untyped-def] return foo function_view = CallableView.from_callable(fn) - assert function_view.parameters == (ParameterView("foo", TypeView(Any)),) + assert function_view.parameters == (ParameterView("foo", TypeView(Any), has_annotation=False),) def test_typed_param() -> None: diff --git a/type_lens/parameter_view.py b/type_lens/parameter_view.py index ad2b85f..22dd39d 100644 --- a/type_lens/parameter_view.py +++ b/type_lens/parameter_view.py @@ -23,18 +23,35 @@ class ParameterView: "name": "The name of the parameter.", "default": "The default value of the parameter.", "type_view": "View of the parameter's annotation type.", + "has_annotation": ( + "Whether the parameter had an annotation or not. Lack of an annotation implies " + "`TypeView(Any)`, but that is distinct from being explicitly `Any` annotated." + ), } - def __init__(self, name: str, type_view: TypeView = _any_type_view, *, default: Any | EmptyType = Empty) -> None: + def __init__( + self, + name: str, + type_view: TypeView = _any_type_view, + *, + default: Any | EmptyType = Empty, + has_annotation: bool = True, + ) -> None: self.name: Final = name self.type_view: Final = type_view self.default: Final = default + self.has_annotation: Final = has_annotation def __eq__(self, other: object) -> bool: if not isinstance(other, ParameterView): return False - return bool(self.name == other.name and self.type_view == other.type_view and self.default == other.default) + return bool( + self.name == other.name + and self.type_view == other.type_view + and self.default == other.default + and self.has_annotation == other.has_annotation + ) def __repr__(self) -> str: cls_name = self.__class__.__name__ @@ -68,5 +85,6 @@ def from_parameter(cls, parameter: Parameter, fn_type_hints: dict[str, Any]) -> return cls( name=parameter.name, default=Empty if parameter.default is Signature.empty else parameter.default, + has_annotation=parameter.annotation is not Signature.empty, type_view=TypeView(annotation), )