-
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
Bump to Python 3.9, Big typing updates #2963
Conversation
Update dependencies minimum package versions to post-3.9 versions. Upgrade latest pyparsing Update to latest MyPy Update to latest Black Re-issue new Poetry lockfile
…estictive, and fix the fallout
# Conflicts: # rdflib/namespace/__init__.py
…atically included in _subjectType, and we don't need a forward-definition for QuotedGraph in _subjectType alias.
…hat set in PyProject toml
b6a7794
to
10bac8d
Compare
Finally after a bunch of extra tweaks to satisfy tests, linters, and doc generation, this is ready to go! |
Nice one! I'm definitely looking forward to the type hint improvements around Graph. Just out of curiosity, I always thought the union type operator |
Hi @edmondchuc I noticed when making these changes, Python 3.9 only allows the Eg, this works: my_str_or_bytes: str | bytes = b"hello" But this does not: StrOrBytesType: TypeAlias = str | bytes # <-- Python interpreter error in v3.9
my_str_or_bytes: StrOrBytesType = b"hello" Because the former is only ready by MyPy, but the latter is evaluated by the interpreter that fails in Python 3.9. I believe that is what has changed in Python 3.10. That is why you will still see code like this in this PR: Line 307 in 73400f3
|
@edmondchuc Do you think we should merge this as-is, or move back to |
Hi Ashley, thanks for the explanation. I think you're right. The union operator works for type annotations but not for when they are interpreted as values. In addition to what you've stated, the reason the from __future__ import annotations Just tested this on python 3.9. Without the above import, it raises a (p39-test) edmondchuc@192-168-1-7 p39-test % python main.py
Traceback (most recent call last):
File "/Users/edmondchuc/test/p39-test/main.py", line 4, in <module>
def foo(value: str | None = None):
TypeError: unsupported operand type(s) for |: 'type' and 'NoneType' I think it's fine to merge as-is. I also think that given this PR is moving towards newer typing syntax, it makes sense to replace the use of - from typing import Optional
- def foo(value: Optional[str] = None): ...
+ def foo(value: str | None = None): ... What do you think? |
@edmondchuc |
Great, a subsequent PR sounds good. |
This is a very large PR.
This represents the first steps in the path to RDFLib 8.
There is a bunch to unpack in this one, this is the summary:
It is step number 7 that makes this PR so huge.
As an example, pre-3.9 typing annotations look like this:
and preferred type annotation style used in Python 3.9+ is like this:
The main differences being that importing basic type classes from the
typing
stdlib module is deprecated in Python 3.9+, for things likeList
,Set
,Dict
,Tuple
, Python 3.9+ supports using the native classes directly as type annotationslist
,set
,dict
,tuple
, etc. The other obvious change is the move away fro theUnion
helper fromtyping
module, because you can simply union types with the bar|
operator in Python 3.9+.Applying these annotation-pattern updates across the whole codebase caused hundreds of files to be modified in this PR.
Applying all these changes along with the bump to latest MyPy and asking MyPy type checker to operate in Python 3.9+ compatibly mode caused some fallout. There were over 250 failing type checks after applying the above changes, that each needed to be investigated and fixed.
The main culprit was RDFLib's existing excessive use of
typing: ignore[]
comments, that were either no longer needed (eg, the type was fixed, and the ignore was redundant which itself is a typing error), or causing their own typing problems. Mosttyping: ignore[]
comments were removed, and where there were still type errors the underlying cause was fixed instead of commented over.Another big contributor to the failures were some incompatibilities with RDFLib's fundamental base types, that were defined like this:
The problem is
Node
is the base classes for many different objects in RDFLib, some of which should not be used as subject or object in a Triple, and most of which cannot be used as the predicate in a triple.So this PR tightens up the typing of
_SubjectType
,_PredicateType
, and_ObjectType
to enforce correct usage of various python objects in triples, at the typing level. In various locations in the code baseinstead of simply usingNode
orIdentifier
annotations for objects in a graph (or serializer or parser), we now use the correct_SubjectType
,_PredicateType
,_ObjectType
where appropriate. This change caused a further 200+ type errors to be emitted from MyPy, all of which needed to be carefully checked and fixed. This exposed many instances where incorrect object types were being used, or edge-cases not considered and dealt with.The remaining portions of this PR are the fixes for those errors. The test suite was used continually throughout the process to ensure the actual behaviour of the executing RDFLib code did not change, and the test suite still passes.
All files were reformatted with latest Black, and Ruff linter with auto-fix used to ensure everything is compliant.