types-lxml-multi-subclass


Nametypes-lxml-multi-subclass JSON
Version 2024.12.13 PyPI version JSON
download
home_pageNone
SummaryComplete lxml external type annotation
upload_time2024-12-13 12:34:29
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseNone
keywords lxml typing stubs annotation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![PyPI version](https://img.shields.io/pypi/v/types-lxml.svg)](https://pypi.org/project/types-lxml/)
![Supported Python](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fabelcheung%2Ftypes-lxml%2Fmain%2Fpyproject.toml
)
![Wheel](https://img.shields.io/pypi/wheel/types-lxml.svg)

## Important note

![image showing deprecation warning](https://github.com/user-attachments/assets/6ab30a54-60e7-4e34-932a-2ac2e253c669)

- Since `2024.11.08`:
  - `pyright` users will see warning if a single string is supplied where collection of string is expected (`tuple`, `set`, `list` etc). In terms of typing, a single `str` itself is valid as a `Sequence`, so type checkers normally would not raise alarm when using `str` in such function parameters, but can induce unexpected runtime behavior. See [#64](https://github.com/abelcheung/types-lxml/issues/64) for more info. `mypy` does not support this feature (which (ab)uses `@deprecated` warning).
  - It is possible to verify release files indeed come from GitHub and not maliciously altered. See [Release file attestation](#release-file-attestation) for detail.
- Since `2024.08.07`:
  - Each release will contain multiple builds; besides normal version, there is an alternative build suitable for multiple XML element subclass. Please check out [relevant Installation section](#choosing-the-build) for detail (hint: many people don't need to bother with this). Also note that this release requires `mypy 1.11` if one chooses to use `mypy` for type checking. `pyright` version requirement (`1.1.351`) is not changed.

## Introduction

This repository contains [external type annotations](https://peps.python.org/pep-0561/) for [`lxml`](http://lxml.de/). It can be used by type-checking tools (currently supporting [`pyright`](https://github.com/Microsoft/pyright) and [`mypy`](https://pypi.org/project/mypy/)) to check code that uses `lxml`, or used within IDEs like [VSCode](https://code.visualstudio.com/) to facilitate development.

## Goal ① : Completion

Now the coverage of `lxml` submodules is complete (unless intentionally rejected, see further below), thus no more [considered as `partial`](https://peps.python.org/pep-0561/#partial-stub-packages):
  - [x] `lxml.etree`
  - [x] `lxml.html`
    - [x] `lxml.html.builder`
    - [x] `lxml.html.clean` (already removed in lxml 5.2.0, this project will follow suite in future)
    - [x] `lxml.html.diff`
    - [x] `lxml.html.html5parser`
    - [x] `lxml.html.soupparser`
  - [x] `lxml.isoschematron`
  - [x] `lxml.objectify`
  - [x] `lxml.builder`
  - [x] `lxml.cssselect`
  - [x] `lxml.sax`
  - [x] `lxml.ElementInclude`

Following submodules will not be implemented due to irrelevance to type checking or other reasons:

  - `lxml.etree.Schematron` (obsolete and superseded by `lxml.isoschematron`)
  - `lxml.usedoctest`
  - `lxml.html.usedoctest`
  - `lxml.html.formfill` (shouldn't have existed, this would belong to HTTP libraries like `requests` or `httpx`)

Check out [project page](https://github.com/abelcheung/types-lxml/projects) for future plans and progress.

## Goal ② : Support multiple type checkers

Currently the annotations are validated for both `pyright` and `mypy`, with `pyright` recommended because of its greater flexibility and early adoption of newer type checking features.

In the future, there is plan to bring even more type checker support.

## Goal ③: Review and test suite

- [x] All prior `lxml-stubs` contributions are reviewed thoroughly, bringing coherency of annotation across the whole package
- [x] Perform runtime check, and compare against static type checker result; this guarantees annotations are indeed working in real world, not just within some cooked up test suite
- [x] Existing static test suite already vastly expanded, and is under progress of migrating to runtime test
- [x] Modernize package building infrastructure

## Goal ④ : Support for IDEs

Despite having no official PEP, some IDEs support showing docstring from external annotations. This package tries to bring type annotation specific docstrings for some `lxml` classes and functions, explaining how they can be used. Following screenshots show what would look like in Visual Studio Code, behaving as if docstrings come from real python code:

![Stub docstring in VSCode mouseover tooltip](https://user-images.githubusercontent.com/83110/277119481-debbd929-afbd-4f59-b9e6-52a1f7f23241.png)

Besides docstring, current annotations are geared towards convenience for code writers instead of absolute logical 'correctness'. The [deviation of class inheritance](https://github.com/abelcheung/types-lxml/wiki/Element-inheritance-change) for `HtmlComment` and friends is one prominent example.


## Installation

The normal choice for most people is to fetch package from PyPI, like:

    uv pip install -U types-lxml  # using uv
    pip install -U types-lxml  # using pip

In the unlikely case PyPI is down, one can directly download wheel from [latest release in GitHub](https://github.com/abelcheung/types-lxml/releases/latest), and then perform installation as local file.

As convenience, it is possible to pull type checker directly [with extras](https://peps.python.org/pep-0508/#extras):

    uv pip install -U types-lxml[pyright]
    pip install -U types-lxml[mypy]

### Choosing the build

Since `2024.08.07` release, there will be two versions of `types-lxml`. First one is the default one; if there's no problem using it, there's no need to switch.

The second version, `types-lxml-multi-subclass`, is intended for specific need, namely creation of multiple lxml element subclasses. For example:

```mermaid
  graph TD;
      etree.ElementBase-->MyBaseElement;
      MyBaseElement-->MySubElement1;
      MyBaseElement-->MySubElement2;
```

If a parsed or constructed element tree consists of single type of element nodes, it is safe to assume the children or parent of a node are of the same type too. But this assumption does not hold for multiple subclasses. Using diagram above as example, calling `.iter()` method from `MyBaseElement` node may produce element of any subelement or even `MyBaseElement` itself.
Therefore output type should be simply `MyBaseElement` only.

Such scenario is already in effect for `lxml.html`. `<form>` element (`FormElement`) is supposed to contain other form related tags like `<input>`, `<select>` etc. But we can't possibly pinpoint single subelement type, so `<form>` children can only possibly be of type `HtmlElement`. The multiple subelement scenario is already hardcoded for `HtmlElement` and `ObjectifiedElement` within this annotation package, but users may choose to have their own overridden element subclasses (inherit from `ElementBase`) too.

The 2 paradigms can't coexist within a single type annotation package. See [bug #51](https://github.com/abelcheung/types-lxml/issues/51) that illustrated why multiple build is necessary.

Remember that anybody can only choose one of the 2 builds. It is impossible to install both, as `pip` just [arbitrarily overwrite conflicting files with one another](https://github.com/pypa/pip/issues/4625). If in doubt, removing existing package first, then install the one you needed.


### Release file attestation

Since `2024.11.08` users can download `types-lxml` release files and verify that they indeed do originate from GitHub. For those haven't heard of it, this is sort of like `gnupg` or [`minisign`](https://jedisct1.github.io/minisign/) signatures, but with GitHub backed infrastructure.

After downloading release wheel file (say `pip download types-lxml`, or browser access to PyPI directly), one can use [GitHub cli](https://cli.github.com/) to verify it comes from this GitHub repository without being altered:

```
gh at verify types_lxml-2024.11.8-py3-none-any.whl --repo abelcheung/types-lxml
```

Should generate following result:

```
Loaded digest sha256:4b4fa7f9e2f1d5f58b98ac9852a75927e4e0f69363249f9cebc78db095c046e0 for file://types_lxml-2024.11.8-py3-none-any.whl
Loaded 1 attestation from GitHub API
✓ Verification succeeded!

sha256:4b4fa7f9e2f1d5f58b98ac9852a75927e4e0f69363249f9cebc78db095c046e0 was attested by:
REPO                   PREDICATE_TYPE                  WORKFLOW
abelcheung/types-lxml  https://slsa.dev/provenance/v1  .github/workflows/release.yml@refs/tags/2024.11.08
```


## History

Type annotations for `lxml` were initially included in [typeshed](https://www.github.com/python/typeshed), but as it was still incomplete at that time, the stubs are [ripped out as a separate project](https://github.com/python/typeshed/issues/525). The code was since then under governance of lxml, until 2022 when this fork intended to revamp `lxml-stubs` completely and emerge into separate project.

`types-lxml` is a fork of `lxml-stubs` that strives for the goals described above, so that most people would find it more useful.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "types-lxml-multi-subclass",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "lxml, typing, stubs, annotation",
    "author": null,
    "author_email": "Abel Cheung <abelcheung@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/25/2a/f25922a75a7e800a93e00f2303bde0126e50c97e04084155f50025e6eb9e/types_lxml_multi_subclass-2024.12.13.tar.gz",
    "platform": null,
    "description": "[![PyPI version](https://img.shields.io/pypi/v/types-lxml.svg)](https://pypi.org/project/types-lxml/)\n![Supported Python](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fabelcheung%2Ftypes-lxml%2Fmain%2Fpyproject.toml\n)\n![Wheel](https://img.shields.io/pypi/wheel/types-lxml.svg)\n\n## Important note\n\n![image showing deprecation warning](https://github.com/user-attachments/assets/6ab30a54-60e7-4e34-932a-2ac2e253c669)\n\n- Since `2024.11.08`:\n  - `pyright` users will see warning if a single string is supplied where collection of string is expected (`tuple`, `set`, `list` etc). In terms of typing, a single `str` itself is valid as a `Sequence`, so type checkers normally would not raise alarm when using `str` in such function parameters, but can induce unexpected runtime behavior. See [#64](https://github.com/abelcheung/types-lxml/issues/64) for more info. `mypy` does not support this feature (which (ab)uses `@deprecated` warning).\n  - It is possible to verify release files indeed come from GitHub and not maliciously altered. See [Release file attestation](#release-file-attestation) for detail.\n- Since `2024.08.07`:\n  - Each release will contain multiple builds; besides normal version, there is an alternative build suitable for multiple XML element subclass. Please check out [relevant Installation section](#choosing-the-build) for detail (hint: many people don't need to bother with this). Also note that this release requires `mypy 1.11` if one chooses to use `mypy` for type checking. `pyright` version requirement (`1.1.351`) is not changed.\n\n## Introduction\n\nThis repository contains [external type annotations](https://peps.python.org/pep-0561/) for [`lxml`](http://lxml.de/). It can be used by type-checking tools (currently supporting [`pyright`](https://github.com/Microsoft/pyright) and [`mypy`](https://pypi.org/project/mypy/)) to check code that uses `lxml`, or used within IDEs like [VSCode](https://code.visualstudio.com/) to facilitate development.\n\n## Goal \u2460 : Completion\n\nNow the coverage of `lxml` submodules is complete (unless intentionally rejected, see further below), thus no more [considered as `partial`](https://peps.python.org/pep-0561/#partial-stub-packages):\n  - [x] `lxml.etree`\n  - [x] `lxml.html`\n    - [x] `lxml.html.builder`\n    - [x] `lxml.html.clean` (already removed in lxml 5.2.0, this project will follow suite in future)\n    - [x] `lxml.html.diff`\n    - [x] `lxml.html.html5parser`\n    - [x] `lxml.html.soupparser`\n  - [x] `lxml.isoschematron`\n  - [x] `lxml.objectify`\n  - [x] `lxml.builder`\n  - [x] `lxml.cssselect`\n  - [x] `lxml.sax`\n  - [x] `lxml.ElementInclude`\n\nFollowing submodules will not be implemented due to irrelevance to type checking or other reasons:\n\n  - `lxml.etree.Schematron` (obsolete and superseded by `lxml.isoschematron`)\n  - `lxml.usedoctest`\n  - `lxml.html.usedoctest`\n  - `lxml.html.formfill` (shouldn't have existed, this would belong to HTTP libraries like `requests` or `httpx`)\n\nCheck out [project page](https://github.com/abelcheung/types-lxml/projects) for future plans and progress.\n\n## Goal \u2461 : Support multiple type checkers\n\nCurrently the annotations are validated for both `pyright` and `mypy`, with `pyright` recommended because of its greater flexibility and early adoption of newer type checking features.\n\nIn the future, there is plan to bring even more type checker support.\n\n## Goal \u2462: Review and test suite\n\n- [x] All prior `lxml-stubs` contributions are reviewed thoroughly, bringing coherency of annotation across the whole package\n- [x] Perform runtime check, and compare against static type checker result; this guarantees annotations are indeed working in real world, not just within some cooked up test suite\n- [x] Existing static test suite already vastly expanded, and is under progress of migrating to runtime test\n- [x] Modernize package building infrastructure\n\n## Goal \u2463 : Support for IDEs\n\nDespite having no official PEP, some IDEs support showing docstring from external annotations. This package tries to bring type annotation specific docstrings for some `lxml` classes and functions, explaining how they can be used. Following screenshots show what would look like in Visual Studio Code, behaving as if docstrings come from real python code:\n\n![Stub docstring in VSCode mouseover tooltip](https://user-images.githubusercontent.com/83110/277119481-debbd929-afbd-4f59-b9e6-52a1f7f23241.png)\n\nBesides docstring, current annotations are geared towards convenience for code writers instead of absolute logical 'correctness'. The [deviation of class inheritance](https://github.com/abelcheung/types-lxml/wiki/Element-inheritance-change) for `HtmlComment` and friends is one prominent example.\n\n\n## Installation\n\nThe normal choice for most people is to fetch package from PyPI, like:\n\n    uv pip install -U types-lxml  # using uv\n    pip install -U types-lxml  # using pip\n\nIn the unlikely case PyPI is down, one can directly download wheel from [latest release in GitHub](https://github.com/abelcheung/types-lxml/releases/latest), and then perform installation as local file.\n\nAs convenience, it is possible to pull type checker directly [with extras](https://peps.python.org/pep-0508/#extras):\n\n    uv pip install -U types-lxml[pyright]\n    pip install -U types-lxml[mypy]\n\n### Choosing the build\n\nSince `2024.08.07` release, there will be two versions of `types-lxml`. First one is the default one; if there's no problem using it, there's no need to switch.\n\nThe second version, `types-lxml-multi-subclass`, is intended for specific need, namely creation of multiple lxml element subclasses. For example:\n\n```mermaid\n  graph TD;\n      etree.ElementBase-->MyBaseElement;\n      MyBaseElement-->MySubElement1;\n      MyBaseElement-->MySubElement2;\n```\n\nIf a parsed or constructed element tree consists of single type of element nodes, it is safe to assume the children or parent of a node are of the same type too. But this assumption does not hold for multiple subclasses. Using diagram above as example, calling `.iter()` method from `MyBaseElement` node may produce element of any subelement or even `MyBaseElement` itself.\nTherefore output type should be simply `MyBaseElement` only.\n\nSuch scenario is already in effect for `lxml.html`. `<form>` element (`FormElement`) is supposed to contain other form related tags like `<input>`, `<select>` etc. But we can't possibly pinpoint single subelement type, so `<form>` children can only possibly be of type `HtmlElement`. The multiple subelement scenario is already hardcoded for `HtmlElement` and `ObjectifiedElement` within this annotation package, but users may choose to have their own overridden element subclasses (inherit from `ElementBase`) too.\n\nThe 2 paradigms can't coexist within a single type annotation package. See [bug #51](https://github.com/abelcheung/types-lxml/issues/51) that illustrated why multiple build is necessary.\n\nRemember that anybody can only choose one of the 2 builds. It is impossible to install both, as `pip` just [arbitrarily overwrite conflicting files with one another](https://github.com/pypa/pip/issues/4625). If in doubt, removing existing package first, then install the one you needed.\n\n\n### Release file attestation\n\nSince `2024.11.08` users can download `types-lxml` release files and verify that they indeed do originate from GitHub. For those haven't heard of it, this is sort of like `gnupg` or [`minisign`](https://jedisct1.github.io/minisign/) signatures, but with GitHub backed infrastructure.\n\nAfter downloading release wheel file (say `pip download types-lxml`, or browser access to PyPI directly), one can use [GitHub cli](https://cli.github.com/) to verify it comes from this GitHub repository without being altered:\n\n```\ngh at verify types_lxml-2024.11.8-py3-none-any.whl --repo abelcheung/types-lxml\n```\n\nShould generate following result:\n\n```\nLoaded digest sha256:4b4fa7f9e2f1d5f58b98ac9852a75927e4e0f69363249f9cebc78db095c046e0 for file://types_lxml-2024.11.8-py3-none-any.whl\nLoaded 1 attestation from GitHub API\n\u2713 Verification succeeded!\n\nsha256:4b4fa7f9e2f1d5f58b98ac9852a75927e4e0f69363249f9cebc78db095c046e0 was attested by:\nREPO                   PREDICATE_TYPE                  WORKFLOW\nabelcheung/types-lxml  https://slsa.dev/provenance/v1  .github/workflows/release.yml@refs/tags/2024.11.08\n```\n\n\n## History\n\nType annotations for `lxml` were initially included in [typeshed](https://www.github.com/python/typeshed), but as it was still incomplete at that time, the stubs are [ripped out as a separate project](https://github.com/python/typeshed/issues/525). The code was since then under governance of lxml, until 2022 when this fork intended to revamp `lxml-stubs` completely and emerge into separate project.\n\n`types-lxml` is a fork of `lxml-stubs` that strives for the goals described above, so that most people would find it more useful.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Complete lxml external type annotation",
    "version": "2024.12.13",
    "project_urls": {
        "homepage": "https://github.com/abelcheung/types-lxml"
    },
    "split_keywords": [
        "lxml",
        " typing",
        " stubs",
        " annotation"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "de19f96dc5a11007fd26eb2ef41cd7dcd6681b6e97bb204bbb91df0d881e9a38",
                "md5": "da4ccc50336461484c9909381050eda8",
                "sha256": "9d28279929ab1f11cc190b7fb1a99e7ccaf946e52da84ab58766c34f5192dbd5"
            },
            "downloads": -1,
            "filename": "types_lxml_multi_subclass-2024.12.13-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "da4ccc50336461484c9909381050eda8",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 86257,
            "upload_time": "2024-12-13T12:34:26",
            "upload_time_iso_8601": "2024-12-13T12:34:26.631809Z",
            "url": "https://files.pythonhosted.org/packages/de/19/f96dc5a11007fd26eb2ef41cd7dcd6681b6e97bb204bbb91df0d881e9a38/types_lxml_multi_subclass-2024.12.13-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "252af25922a75a7e800a93e00f2303bde0126e50c97e04084155f50025e6eb9e",
                "md5": "3722f2d2037a34733c0e16d46a9b0a37",
                "sha256": "bd844512e36a9ef9094a892e84547a241ecd49e3a5ed91d48353482aba9fa019"
            },
            "downloads": -1,
            "filename": "types_lxml_multi_subclass-2024.12.13.tar.gz",
            "has_sig": false,
            "md5_digest": "3722f2d2037a34733c0e16d46a9b0a37",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 130373,
            "upload_time": "2024-12-13T12:34:29",
            "upload_time_iso_8601": "2024-12-13T12:34:29.471618Z",
            "url": "https://files.pythonhosted.org/packages/25/2a/f25922a75a7e800a93e00f2303bde0126e50c97e04084155f50025e6eb9e/types_lxml_multi_subclass-2024.12.13.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-12-13 12:34:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "abelcheung",
    "github_project": "types-lxml",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "types-lxml-multi-subclass"
}
        
Elapsed time: 0.38711s