Skip to content

Re-export binding versions to satisfied mypy --strict#31

Open
bact wants to merge 2 commits intospdx:mainfrom
bact:reexport-binding-versions
Open

Re-export binding versions to satisfied mypy --strict#31
bact wants to merge 2 commits intospdx:mainfrom
bact:reexport-binding-versions

Conversation

@bact
Copy link
Copy Markdown
Collaborator

@bact bact commented Apr 14, 2026

Modify the __init__.py generation so that bindings for each SPDX version will be re-exported.
To fix mypy compatibility when strict=true.

Currently this code:

from spdx_python_model import v3_0_1

will cause mypy (strict=true) error as:

Module "spdx_python_model" has no attribute "v3_0_1"

Modify the `__init__.py` generation so that bindings for each SPDX version will be re-exported.
To fix mypy strict compatibility when enable strict=true in mypy.

Currently this code:

`from spdx_python_model import v3_0_1`

will cause mypy (strict=true) error as:

`Module "spdx_python_model" has no attribute "v3_0_1"`

Signed-off-by: Arthit Suriyawongkul <arthit@gmail.com>
@bact bact added the enhancement New feature or request label Apr 14, 2026
@bact
Copy link
Copy Markdown
Collaborator Author

bact commented Apr 14, 2026

The generated spdx_python_model/__init__.py will be:

# SPDX-License-Identifier: Apache-2.0
#
# Generated by generate-bindings at build time. DO NOT EDIT.
"""SPDX model in Python."""

from .bindings import v3_0_1
from .version import VERSION

__all__ = [
    "VERSION",
    "v3_0_1",
]

The generated spdx_python_model/bindings/__init__.py will be:

# SPDX-License-Identifier: Apache-2.0
#
# Generated by generate-bindings at build time. DO NOT EDIT.
"""SPDX model in Python — all supported SPDX versions."""

from . import v3_0_1

__all__ = [
    "v3_0_1",
]

The generated actual bindings will be handled normally by shacl2code.

@benjarobin
Copy link
Copy Markdown
Contributor

I never noticed that, but is it a good ideal to load all binding versions from __init__?
Most of the time, an application only cares for a specific version. We are really slowing down the startup of applications by importing unnecessary versions.
Currently this is not an issue, since there is only one binding version.

@bact
Copy link
Copy Markdown
Collaborator Author

bact commented Apr 14, 2026

The current implementation loads *, which is effectively all versions.

We can also ask the developers to do

from spdx_python_model.bindings import v3_0_1

instead.

That would be cleaner.
(Need to update code examples in README in that case)

@benjarobin
Copy link
Copy Markdown
Contributor

This is a breaking change. I am proposing to remove the import * (concerning the versions) from the __init__ .

And I prefer to change that as soon as possible. This way we are not living with this "issue" forever.

@bact
Copy link
Copy Markdown
Collaborator Author

bact commented Apr 14, 2026

This is a breaking change. I am proposing to remove the import * (concerning the versions) from the __init__ .

We have several __init__.py. Do you mean this one at the top-level?

from .bindings import *
from .version import VERSION

(Btw, this file is not part of current generation script, it will be used as-is.
The generation script in this PR will overwrite this file.)

That the file will be overwritten at build time.

Signed-off-by: Arthit Suriyawongkul <arthit@gmail.com>
@benjarobin
Copy link
Copy Markdown
Contributor

The goal is when doing from spdx_python_model.bindings import v3_0_1 or something similar to import the binding of version 3.0.1, we do not want to load other versions, we only wants to load the verson 3.0.1.

If I am not mistaken, when doing from spdx_python_model.bindings import v3_0_1 some __init__ are executed.

@bact
Copy link
Copy Markdown
Collaborator Author

bact commented Apr 14, 2026

The goal is when doing from spdx_python_model.bindings import v3_0_1 or something similar to import the binding of version 3.0.1, we do not want to load other versions, we only wants to load the verson 3.0.1.

Agree and want to see that too.

The question here is how to deal with a statement like:

from spdx_python_model import v3_0_1

If we are to allow it (like it currently is), we need to import and re-export v3_0_1 in top-level __init__.py.

We can remove the import/re-export there, but that will be a breaking change for people who do import v3_0_1 that way.

(Anyway, since we are in 0.0.x version line, breaking changes should not be a surprise, if we need to)

@benjarobin
Copy link
Copy Markdown
Contributor

As I said, this is a (major) breaking change.
This is no longer going to work: from spdx_python_model import v3_0_1.
Between v0.0.4 and version v0.0.5 there was also a major breaking change (compatibility was broken because shacl2code >= 1.0.0 was used, which changed various things).

@bact
Copy link
Copy Markdown
Collaborator Author

bact commented Apr 14, 2026

Thank you. I will open another PR to propose an alternative from this PR, based on our discussion. It will introduce a breaking change (while this PR will not).

The goal is to improve resource efficiency (when SPDX versions are growing) by moving away from import * in init.py, so we only load modules as needed instead of loading unused components. (Note that this is not currently an issue because there's only one version to load and by definition nothing is unused).

It should also keep typing annotation accurate (as intended similarly in this PR).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants