Skip to content
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

PEP489 support: multi-phase module initialization, heap based types #307

Merged
merged 44 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f365aff
refactor: one static decl per line
tseaver May 23, 2024
c2f31b1
feat: add struct for module state
tseaver May 23, 2024
14a68b1
feat: wire module state into module def
tseaver May 23, 2024
7d003c1
refactor: return state pointer from 'zic_state_init'
tseaver May 23, 2024
61c3abb
refactor: outline multi-phase initialization
tseaver May 23, 2024
de30f27
fix: store types in module state as PyTypeObject
tseaver May 23, 2024
f2e6838
feat: add module-state version of 'import_declarations'
tseaver May 23, 2024
7b092d9
chore: reformat to Mozilla style w/ indent == 4
tseaver May 23, 2024
fc38083
refactor: use 'PyObject_GetAttrString'
tseaver May 23, 2024
4f5814d
refactor: move docstring decls to just before their functions
tseaver May 23, 2024
6fc0d08
chore: restore compat w/ Python < 3.10
tseaver May 23, 2024
6e1387e
refactor: convert PyType decls to use named members
tseaver May 23, 2024
2c4d70c
refactor: use 'PyDict_GetItemString'
tseaver May 23, 2024
011a705
chore: note reason for avoiding 'PyDict_GetString'
tseaver May 23, 2024
5638a90
refactor: always pass the module to the module-scope functions
tseaver May 23, 2024
f7b2889
refactor: move module-scope functions to end
tseaver May 23, 2024
2b331f9
fix: use API to get initialized module from spec
tseaver May 23, 2024
8b55439
refactor: remove statics loaded from 'z.i.declarations'
tseaver May 23, 2024
02f56e0
chore: cleanups
tseaver May 23, 2024
c573b27
refactor: remove global static 'adapter_hooks'
tseaver May 23, 2024
80ed5e1
refactor: reorder statics above forwards
tseaver May 23, 2024
baf7991
refactor: disuse static 'SpecificationBaseType'
tseaver May 23, 2024
1c5e0ea
refactor: move util funcs out of module init space
tseaver May 23, 2024
e3f947b
refactor: multi-phase module init + heap types
tseaver May 23, 2024
0e315d8
chore: work around 'InterfaceBase.__module__' returning descriptor
tseaver May 23, 2024
4b3e9db
refactor: use 'Py_TPFLAGS_MANAGED_WEAKREF' everywhere
tseaver May 23, 2024
5de904c
refactor: macros for type flags
tseaver May 23, 2024
c642bb0
refactor: use better name for the C base classes
tseaver May 23, 2024
8d9086c
refactor: restore use of static types for Python < 3.11
tseaver May 25, 2024
a03b255
Merge branch 'master' into tseaver-rework_pep_489
tseaver May 26, 2024
45f086d
Merge branch 'master' into tseaver-rework_pep_489
tseaver May 27, 2024
2bb0ee6
tests: doctests pass under 'pypy3'
tseaver May 27, 2024
bcc27b7
Merge branch 'master' into tseaver-rework_pep_489
tseaver May 28, 2024
bc55fcb
perf: re-intern hot-path getattr names
tseaver May 28, 2024
61a84a1
refactor: limit special-case handling to 'InterfaceBase'
tseaver Jun 12, 2024
e0558d7
Merge branch 'master' into tseaver-rework_pep_489
tseaver Aug 1, 2024
e173384
chore: document version hex usage
tseaver Aug 1, 2024
ee3efff
chore: drop use of obscure acronym in comment
tseaver Aug 1, 2024
743903d
chore: another acronym bites the dust
tseaver Aug 1, 2024
d6f5640
chore: fix typos in comments
tseaver Aug 1, 2024
21603e6
Merge branch 'tseaver-rework_pep_489' of github.com:zopefoundation/zo…
tseaver Aug 1, 2024
25d664a
chore: link to C API howto for Python 3.8 quirk
tseaver Aug 1, 2024
6bb37a5
refactor: use named flag for explicit weakref lists
tseaver Aug 1, 2024
c35f95e
chore: clarify condition for visiting the type object
tseaver Aug 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions docs/verify.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ defined.
.. doctest::

>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo:
The object <...Foo...> has failed to implement interface ...IFoo:
Does not declaratively implement the interface
The base.IBase.x attribute was not provided
The module.IFoo.y attribute was not provided
Expand All @@ -61,7 +61,7 @@ declaring the correct interface.

>>> Foo.x = Foo.y = 42
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo: Does not declaratively implement the interface.
The object <...Foo...> has failed to implement interface ...IFoo: Does not declaratively implement the interface.

If we want to only check the structure of the object, without examining
its declarations, we can use the ``tentative`` argument.
Expand Down Expand Up @@ -125,13 +125,13 @@ exception.
... class Foo(object):
... x = 1
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo: The module.IFoo.y attribute was not provided.
The object <...Foo...> has failed to implement interface ...IFoo: The module.IFoo.y attribute was not provided.
>>> @implementer(IFoo)
... class Foo(object):
... def __init__(self):
... self.y = 2
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo: The base.IBase.x attribute was not provided.
The object <...Foo...> has failed to implement interface ...IFoo: The base.IBase.x attribute was not provided.

If both attributes are missing, an exception is raised reporting
both errors.
Expand All @@ -142,7 +142,7 @@ both errors.
... class Foo(object):
... pass
>>> verify_foo()
The object <Foo ...> has failed to implement interface ...IFoo:
The object <...Foo ...> has failed to implement interface ...IFoo:
The base.IBase.x attribute was not provided
The module.IFoo.y attribute was not provided

Expand All @@ -161,7 +161,7 @@ when trying to get its value, the attribute is considered missing:
... def x(self):
... raise AttributeError
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo: The module.IFoo.x attribute was not provided.
The object <...Foo...> has failed to implement interface ...IFoo: The module.IFoo.x attribute was not provided.


Any other exception raised by a property will propagate to the caller of
Expand Down Expand Up @@ -209,7 +209,7 @@ that takes one argument. If we don't provide it, we get an error.
... class Foo(object):
... pass
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo: The module.IFoo.simple(arg1) attribute was not provided.
The object <...Foo...> has failed to implement interface ...IFoo: The module.IFoo.simple(arg1) attribute was not provided.

Once they exist, they are checked to be callable, and for compatible signatures.

Expand All @@ -219,7 +219,7 @@ Not being callable is an error.

>>> Foo.simple = 42
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo: The contract of module.IFoo.simple(arg1) is violated because '42' is not a method.
The object <...Foo...> has failed to implement interface ...IFoo: The contract of module.IFoo.simple(arg1) is violated because '42' is not a method.

Taking too few arguments is an error. (Recall that the ``self``
argument is implicit.)
Expand All @@ -228,15 +228,15 @@ argument is implicit.)

>>> Foo.simple = lambda self: "I take no arguments"
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo: The contract of module.IFoo.simple(arg1) is violated because '<lambda>()' doesn't allow enough arguments.
The object <...Foo...> has failed to implement interface ...IFoo: The contract of module.IFoo.simple(arg1) is violated because '<lambda>()' doesn't allow enough arguments.

Requiring too many arguments is an error.

.. doctest::

>>> Foo.simple = lambda self, a, b: "I require two arguments"
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo: The contract of module.IFoo.simple(arg1) is violated because '<lambda>(a, b)' requires too many arguments.
The object <...Foo...> has failed to implement interface ...IFoo: The contract of module.IFoo.simple(arg1) is violated because '<lambda>(a, b)' requires too many arguments.

Variable arguments can be used to implement the required number, as
can arguments with defaults.
Expand All @@ -263,7 +263,7 @@ variable keyword arguments, the implementation must also accept them.
... class Foo(object):
... def needs_kwargs(self, a=1, b=2): pass
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo: The contract of module.IFoo.needs_kwargs(**kwargs) is violated because 'Foo.needs_kwargs(a=1, b=2)' doesn't support keyword arguments.
The object <...Foo...> has failed to implement interface ...IFoo: The contract of module.IFoo.needs_kwargs(**kwargs) is violated because 'Foo.needs_kwargs(a=1, b=2)' doesn't support keyword arguments.

>>> oname, __name__ = __name__, 'module'
>>> class IFoo(Interface):
Expand All @@ -273,7 +273,7 @@ variable keyword arguments, the implementation must also accept them.
... class Foo(object):
... def needs_varargs(self, **kwargs): pass
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo: The contract of module.IFoo.needs_varargs(*args) is violated because 'Foo.needs_varargs(**kwargs)' doesn't support variable arguments.
The object <...Foo...> has failed to implement interface ...IFoo: The contract of module.IFoo.needs_varargs(*args) is violated because 'Foo.needs_varargs(**kwargs)' doesn't support variable arguments.

Of course, missing attributes are also found and reported, and the
source interface of the missing attribute is included. Similarly, when
Expand All @@ -294,7 +294,7 @@ the failing method is from a parent class, that is also reported.
... class Foo(Base):
... pass
>>> verify_foo()
The object <Foo...> has failed to implement interface ...IFoo:
The object <...Foo...> has failed to implement interface ...IFoo:
The contract of base.IBase.method(arg1) is violated because 'Base.method()' doesn't allow enough arguments
The module.IFoo.x attribute was not provided

Expand Down
Loading
Loading