diff --git a/build.py b/build.py index 4672c3b8f..1e34bb237 100755 --- a/build.py +++ b/build.py @@ -1297,8 +1297,8 @@ def cmd_sip(options, args): continue # Leave it turned off for now. TODO: Experiment with this... - # pyi_extract = posixjoin(cfg.PKGDIR, base[1:]) + '.pyi' - pyi_extract = None + pyi_extract = posixjoin(cfg.PKGDIR, base[1:]) + '.pyi' + # pyi_extract = None # SIP extracts are used to pull python snippets and put them into the # module's .py file @@ -1320,13 +1320,14 @@ def cmd_sip(options, args): tracing = {tracing} protected-is-public = false generate-extracts = [\'{extracts}\'] - pep484-pyi = false + pep484-pyi = true [tool.sip.project] abi-version = "{abi_version}" sip-files-dir = '{sip_gen_dir}' sip-include-dirs = ['{src_dir}'] sip-module = "wx.siplib" + dunder-init = true """.format( base=base, abi_version=cfg.SIP_ABI, @@ -2131,7 +2132,7 @@ def cmd_cleanall(options, args): cmdTimer = CommandTimer('cleanall') assert os.getcwd() == phoenixDir() files = list() - for wc in ['sip/cpp/*.h', 'sip/cpp/*.cpp', 'sip/cpp/*.sbf', 'sip/gen/*.sip']: + for wc in ['sip/cpp/*.h', 'sip/cpp/*.cpp', 'sip/cpp/*.pyi', 'sip/cpp/*.sbf', 'sip/gen/*.sip']: files += glob.glob(wc) delFiles(files) @@ -2209,6 +2210,15 @@ def _archive_submodules(root, dest): copyFile(name, destdir) sip_h_dir = posixjoin(cfg.PKGDIR, 'include', 'wxPython') copyFile(posixjoin(sip_h_dir, 'sip.h'), posixjoin(PDEST, sip_h_dir)) + print("Copy sip-generated pyi files") + # Copy sip-generated pyi files + for sip_pyi in glob.glob(posixjoin('sip','cpp','*.py*')): + print(f"Found {sip_pyi}") + destdir = posixjoin(PDEST, cfg.PKGDIR) + if not os.path.isdir(sip_pyi): + copyFile(sip_pyi, destdir) + print(f"Copied '{sip_pyi}' to dir '{destdir}'") + print("Finished copying sip-generated pyi files") for wc in ['*.py', '*.pi', '*.pyi']: destdir = posixjoin(PDEST, cfg.PKGDIR) for name in glob.glob(posixjoin(cfg.PKGDIR, wc)): diff --git a/etg/dc.py b/etg/dc.py index 5cbac842f..29fee33c3 100644 --- a/etg/dc.py +++ b/etg/dc.py @@ -282,8 +282,19 @@ def run(): c.addPyCode('DC.GetGdkDrawable = wx.deprecated(DC.GetGdkDrawable, "Use GetHandle instead.")') # context manager methods - c.addPyMethod('__enter__', '(self)', 'return self') - c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'self.Destroy()') + c.module.addPyCode(""" +from types import TracebackType +from typing import TYPE_CHECKING, Literal +if TYPE_CHECKING: + import sys + if sys.version_info >=(3,11): + from typing import Self + else: + from typing import TypeVar + import wx.core.DC + Self = TypeVar("Self", bound="wx.core.DC")""") + c.addPyMethod('__enter__', '(self: Self) -> Self', 'return self') + c.addPyMethod('__exit__', '(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> Literal[False]', 'self.Destroy()') # This file contains implementations of functions for quickly drawing diff --git a/etgtools/pi_generator.py b/etgtools/pi_generator.py index 42a540f31..006e6a9d8 100644 --- a/etgtools/pi_generator.py +++ b/etgtools/pi_generator.py @@ -267,9 +267,18 @@ def generateTypedef(self, typedef, stream, indent=''): bases = [self.fixWxPrefix(b, True) for b in bases] name = self.fixWxPrefix(typedef.name) + print(f"Vars of typedef : {vars(typedef)}") + baseClassSip = None + if hasattr(typedef, "module"): + print(f"Vars of typedef.module : {vars(typedef.module)}") + baseClassSip = typedef.module.module+"."+name + bases += [baseClassSip] + else: + print("typedef doesn't have a modules attribute") + # Now write the Python equivalent class for the typedef if not bases: - bases = ['object'] # this should not happen, but just in case... + bases = ['object'] # this should not happen, but just in case... stream.write('%sclass %s(%s):\n' % (indent, name, ', '.join(bases))) indent2 = indent + ' '*4 if typedef.briefDoc: @@ -407,14 +416,26 @@ def generateClass(self, klass, stream, indent=''): # write class declaration klassName = klass.pyName or klass.name + print(f"Vars of klass : {vars(klass)}") + baseClassSip = None + if hasattr(klass, "module"): + print(f"Vars of klass.module : {vars(klass.module)}") + baseClassSip = klass.module.module+"."+klassName + else: + print("klass doesn't have a modules attribute") stream.write('\n%sclass %s' % (indent, klassName)) if bases: stream.write('(') bases = [self.fixWxPrefix(b, True) for b in bases] + if baseClassSip is not None: + bases += [baseClassSip] stream.write(', '.join(bases)) stream.write(')') else: - stream.write('(object)') + if baseClassSip is None: + stream.write(f'(object)') + else: + stream.write(f'(object, {baseClassSip})') stream.write(':\n') indent2 = indent + ' '*4 diff --git a/etgtools/sip_generator.py b/etgtools/sip_generator.py index 38db80b1d..a30196aeb 100644 --- a/etgtools/sip_generator.py +++ b/etgtools/sip_generator.py @@ -80,6 +80,8 @@ def generateModule(self, module, stream): %%DefaultDocstringFormat(name="deindented") +%%DefaultDocstringSignature(name="appended") + """ % (module.package, module.name)) if module.name.startswith('_'): diff --git a/wx/lib/busy.py b/wx/lib/busy.py index 49e7a26cc..ed0ec28e6 100644 --- a/wx/lib/busy.py +++ b/wx/lib/busy.py @@ -12,9 +12,20 @@ A class like :class:`wx.BusyInfo` but which doesn't take up so much space by default and which has a nicer look. """ +from __future__ import annotations import wx from wx.lib.stattext import GenStaticText as StaticText +from types import TracebackType +from typing import TYPE_CHECKING, Literal +if TYPE_CHECKING: + import sys + if sys.version_info >=(3,11): + from typing import Self + else: + from typing import TypeVar + import wx.lib.busy + Self = TypeVar("Self", bound="wx.lib.busy.BusyInfo") #--------------------------------------------------------------------------- @@ -68,9 +79,9 @@ def Close(self): # Magic methods for using this class as a Context Manager - def __enter__(self): + def __enter__(self: Self) -> Self: return self - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> Literal[False]: self.Close() return False diff --git a/wx/py.typed b/wx/py.typed new file mode 100644 index 000000000..c4e267062 --- /dev/null +++ b/wx/py.typed @@ -0,0 +1 @@ +partial