-
Notifications
You must be signed in to change notification settings - Fork 555
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
Start support for mypy --strict #1515
Start support for mypy --strict #1515
Conversation
This patch is believed to be part of what would be necessary to resolve Issue 1447. This patch addresses type errors raised by `mypy` pertaining to use of untyped methods within typed contexts. These signatures are sufficient to pass a test application (coming in a following patch) that exercises: * creation of a graph; * use of `Graph.add()` to supply triples containing `URIRef`, `BNode`, and `Literal` objects; * use of `Graph.triples()`; * use of `Graph.query()` with a string argument; * use of `Graph.query()` with a `Query` argument; * use of `Graph.query()` to return query results with different bound-variable lengths (i.e. different tuple lengths); and * use of several `.toPython()` methods, including `Literal.toPython()`. To address issues with the various `Node` subclasses appearing to be untyped on initialization, this patch introduces `__init__` methods to satisfy `mypy` needing a type signature. To support any future initialization logic, `super()` is used to support the Method Resolution Order chain. The alternative approach of trying to assign return types to `__new__` didn't seem to work for two reasons that would require more significant design revision: * `BNode.__new__()` returns an `Identifier`, and `mypy` complained that this is an incompatible return type. Attempting `typing.cast()` didn't seem to resolve this problem. * `Literal.__new__()` was raising this `mypy --strict` error: ``` "Literal" has no attribute "_value"; maybe "value"? ``` I can't think of a practice aside from exposing `_value` as a slot that would convince `mypy` that the field exists. Hence, the classes under `rdflib/term.py` got `__init__()` methods. References: * RDFLib#1447 * https://stackoverflow.com/a/33533514 describes PEPs 484 and 563 relative to this patch. Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
…ypes This test is anchored off of Issue 1447, trying to identify "common" functions that would be used in a script exercising multiple SPARQL queries that return Python values. References: * RDFLib#1447 * python/typing#911 Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
…nsumer Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Thanks for this, I will have a look at it tomorrow night. |
Well, that's an unfortunate series of X's. The call to I determined the difference is in how the package install is run:
Of course, all of my testing directly with this repository was with the last three modes. (Modes 4 and 5 were how I tested these modifications in other So, I guess I need to highlight my original question 2 - how and where would it be appropriate---and heck, even functional---for |
Evidence of the |
I'm not entirely sure if this pattern is considered ideal - I know it has been used but there has also been some resistance to it, and I would say I somewhat agree that it may be better to try and decouple tests from the issue they were in. I think a name like I made a pull request to update the developers guide on where tests should go (#1517) and will run it past others to see what the consensus is on this. I think for now it is fine, but the file name may need to change later.
I think ideally this should be setup in So that will entail something like this in setup.cfg: [mypy]
python_version = 3.7
warn_unused_configs = True
ignore_missing_imports = True
disallow_subclassing_any = False
warn_unreachable = True
[mypy-test.test_issue1447]
strict = True I have tried it thought and it is not quite doing what I'm expecting, there are some other fallbacks but I will try a couple of things to get it working. Will respond to other points when I can, hopefully tomorrow. |
@ajnelson-nist I made a PR against your branch to make the validation pass with the selective files running in strict mode: ajnelson-nist#8 Would recommend a rebase onto master though as there has been a couple of changes related to mypy and typing since your branch. |
- Changed all mypy invocation to not include paths and moved the paths to the mypy section in setup.cfg. This removes redudancy in directory specification and reduces the potential that directories are changed in one invocation but not others. - Ignore mypy errors in test directory. - Enable strict mypy config with in-file config comments in the following files: - test/test_issue1447.py - test/test_issue_git_336.py - test/test_literal.py - test/test_parse_file_guess_format.py
Please merge ajnelson-nist#9 so that you are adding typing to |
mypy has an option:
This is enabled in --strict mode:
For more info see https://mypy.readthedocs.io/en/stable/config_file.html#confval-implicit_reexport |
Maybe: Subject = typing.Union[rdflib.BNode, rdflib.URIRef] After all, from https://www.w3.org/TR/rdf11-concepts/#section-triples
|
For now typing We need to add a lot more typing to help figure out the tightest constraints that make sense, but your changes are a step in the right direction and best to keep them minimal and merge them. I have a bunch more typing changes that are not in PRs yet, and there are a lot more to add, but it is easier if we make them in small batches - it will take some time getting to the point where everything works in strict mode. |
If you give me access to your branch then I can do some rebases and merge the PRs I made, up to you of course - don't mind either way - but I want to keep this mergeable so we can get it in as soon as we are ready and so it does not hold up other typing changes that will be made. |
I think in the long run we should just get mypy passing on test directory without strict, and then generally start adding additional errrors/warnings - not something to add here, but just a general view on what to do to get things moving along. |
Fix mypy settings to run select test files in strict mode
Type __new__ instead of adding __init__
This follows through with Iwan's suggestion to type `__new__` instead of adding `__init__`. `Node.__init__` becomes a vestigial addition with his patch. Reported-by: Iwan Aucamp <aucampia@gmail.com> Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Reported-by: Iwan Aucamp <aucampia@gmail.com> Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Reported-by: Iwan Aucamp <aucampia@gmail.com> Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
I'm happy with this change, something which is maybe debatable is on which test files strict mode makes sense. I'm fine with it on the ones you enabled it for but would just want the other maintainers to give some feedback there. (CC: @ashleysommer @nicholascar @white-gecko ). As I said in a comment before, I want to make |
Reported-by: Iwan Aucamp <aucampia@gmail.com> Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
This is just to fit with practice used in other places in this repository. This patch has no impact on function. Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
I've adjusted a few more style matters, but otherwise think this patch series is ready for review and merge. @aucampia , I agree with the general direction of eventually removing |
Also, it seems I'm getting some CI chaos from networking-stack tests. Hopefully that doesn't confuse review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely steps in the right direction! Yes the literal typing is still not great. Last year I added a whole bunch more tests for literal types but not mypy or type hinting. It gets really hard to cater for all XSD datatypes AND Python datatypes AND custom datatypes since there's no guarentee that they all line up.
This patch series attempts to begin a "80/20" strategy suggested on other Issue threads (cited in References) around finding "most commonly used APIs" to address issues introduced with the addition of the
py.typed
file.The first patches are the minimal necessary to get
mypy --strict
to pass on the test programtest/test_issue1447.py
, which exercises (IIRC, all of) therdflib
functions I've used across several projects. Overall, the patch series adds annotations to methods underrdflib/
, annotations to a few existing tests undertest/
, a new test undertest/
, and a practice of running the new and just-revised tests tomypy --strict
in the various testing infrastructures. Feedback is welcome on some of the type-supporting decisions (especially what I call out as worth squinting eyes) and the sustainability of the testing practice.I have a few outstanding questions that would be good to answer before merging this PR, and/or give their own Issues if you'd rather merge sooner:
mypy --strict
be called? Woulddocker-compose.tests.yml
get anothercommand:
line to runmypy --strict
on just that file? Issue 1513 came up as I was testing things, and my initial two guesses of whichmypy
call to revise weren't what ended up being revised, whereas my draft of this PR noted the docker script that has its ownmypy
step, and I missed that Github Actions seems to be what runs the CI now. I'm proceeding in this PR with just modifying Github Actions.rdflib
class name or type designation forNode
s that are notLiteral
s, analogous to SHACL'ssh:BlankNodeOrIRI
? I frequently find the need to define aUnion
type like I did in the test program.prepareQuery
is not exposed tomypy
viardflib/plugins/sparql/__init__py
, while the test program itself would run just fine callingrdflib.plugins.sparql.prepareQuery()
. Any ideas?Literal.toPython()
to work. The first patch makes that the only.toPython
method that is typed returningAny
, while the rest returnstr
. It's possible to make it return aUnion
of types from the various mapping dictionaries, but that causes extra work (eitherassert
ortyping.cast
) for any caller trying to passmypy --strict
. As written in the first patch, the typing and value-testing requires minimal amount of annotation work. Does this practice pass your review, though?Test status:
pytest
,mypy
, andblack
continue to pass as well as they did, as parameterized in.github/workflows/validate.yml
andMakefile
, before the addition of this patch. For review notes:black
currently reports 4 formatting errors in files not touched by this patch series, which I see is|| true
'd out in the Github Actions CI.test/test_xmlliterals.py::testHTML
currently fails in themaster
branch on my laptop, though, I'm not sure why it's passing on the Github Actions CI.I'll do catch-up
merge
s if someone lets me know that either is fixed, even arebase
if you prefer seeing PRs with all patches bearing a green checkmark from CI.References:
Disclaimer:
Participation by NIST in the creation of the documentation of mentioned software is not intended to imply a recommendation or endorsement by the National Institute of Standards and Technology, nor is it intended to imply that any specific software is necessarily the best available for the purpose.