aboutsummaryrefslogtreecommitdiffstats
path: root/sources
Commit message (Collapse)AuthorAgeFilesLines
* libpyside: Fix parameters for connections with contextsFriedemann Kleint2024-07-044-24/+64
| | | | | | | | | | | Use the new SignalManager::callPythonMetaMethod() overload introduced by ed8fc457e04f4ead8a3b2a2da797bdc14bd5b210 in PySideQSlotObject to convert the void ** arguments to Python. Amends acab25a3ccb836818e5089b23d40196bc7414b7a. Change-Id: I024bc7f8df7fa65b8b1761f517a99a854de2cec8 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
* libpyside: Decouple SignalManager::callPythonMetaMethod() from QMetaMethodFriedemann Kleint2024-07-042-48/+123
| | | | | | | | Extract a helper for calling Python slots and add an overload that only takes a list of parameter types and return type. Change-Id: I407c3b1ae66eb4f01370ceac3112eb9407796efa Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
* libpyside: Fix QObject.connectNotify()Friedemann Kleint2024-07-043-8/+2
| | | | | | | | | | | | QObject::connectNotify() is meant to be called with the signal method. The code retrieved the signal method from the receiver though, potentially causing an index violation. Fix it to use the source. Remove misleading comments from 4edd9a1278efdf37f366e9aa6e82f151a357ef32. Change-Id: Id5afdde16ce002e156710128e9610804b748be74 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
* Fix audio_test.py on Kubuntu 22.04Friedemann Kleint2024-07-031-1/+9
| | | | | | | | | The audio device returned an unknown format as preferred one, build a minimal format. Pick-to: 6.7 Change-Id: Ib9a4db805d2993575aaed066de2ab7e123409f88 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* Avoid parenting of QNetworkReply on QNetworkAccessManager in request functionsFriedemann Kleint2024-07-021-6/+50
| | | | | | | | | Suppress return value heuristics for them. Pick-to: 6.7 Task-number: PYSIDE-1057 Change-Id: Id249d8c769f808600545f7a48861bd4fe7eae6fe Reviewed-by: Christian Tismer <tismer@stackless.com>
* Avoid parenting of QModbusReply on QModbusClient in the request functionsFriedemann Kleint2024-07-021-1/+22
| | | | | | | | | Suppress return value heuristics for them. Pick-to: 6.7 Task-number: PYSIDE-2793 Change-Id: I4ebf8c971b02fb00b9c6658b02157eb26d71f418 Reviewed-by: Christian Tismer <tismer@stackless.com>
* Fix non-unity build compilation error: anystringview_helpers.hFrancisco Boni2024-06-291-0/+1
| | | | | | | | | | | Fixes non-unity build compilation error in anystringview_helpers.h (missing qsizetype). Amends 16098891ad21c2ba984582a1de770e49f961f22b. Pick-to: 6.7 Task-number: PYSIDE-2792 Fixes: PYSIDE-2804 Change-Id: Ia6d08ce162c66464da5325f53fa564c7a3c6cce6 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* QtAsyncio: Use modern typing syntaxAdrian Herrmann2024-06-284-87/+81
| | | | | | | | | | | We can already use the modern typing syntax introduced with Python 3.10 in 3.9 via future statement definitions, even before we raise the minimum Python version to 3.10. Task-number: PYSIDE-769 Task-number: PYSIDE-2786 Change-Id: I560d0c25f3503217f920906a5b26193282b0247b Reviewed-by: Christian Tismer <tismer@stackless.com>
* QtAsyncio: Properly document run() argsAdrian Herrmann2024-06-271-1/+19
| | | | | | | | | Properly document the arguments to QtAsyncio.run() with a docstring instead of leaving it only to the module rst. Task-number: PYSIDE-769 Change-Id: Ia4d63b3cdf81d052203a2752ed3ca6cb0b40f814 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
* QtAsyncio: Remove application arg from loop policyAdrian Herrmann2024-06-273-8/+10
| | | | | | | | | | | | | Remove the optional application argument from the constructor of QAsyncioEventLoopPolicy, as it is unnecessary. If a QCoreApplication or other type of qApp was created outside of QtAsyncio, it will always be retrieved by QCoreApplication.instance(), and therefore passing it as an argument makes little sense. Task-number: PYSIDE-769 Change-Id: Iac7a913a1c9d6ebbb0984fe11f8b5cda955baab1 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Christian Tismer <tismer@stackless.com>
* Add warning when adding a Python-declared property failsFriedemann Kleint2024-06-271-2/+17
| | | | | | Pick-to: 6.7 Change-Id: I3b460f270965706a1b8ed04ef6f51d540db3ba72 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* Desktop Deployment: Update Nuitka to 2.3.7Shyamnath Premnadh2024-06-263-4/+4
| | | | | | | | | | | | - Fixes sporadic crashes with Python 3.12 - Supports Numpy 2.0. This is not relevant for us currently, but it's good to have the latest version. Pick-to: 6.7 Fixes: PYSIDE-2781 Task-number: PYSIDE-1612 Change-Id: I96a437795018792906ba6cf44e6466dacc154dbf Reviewed-by: Christian Tismer <tismer@stackless.com>
* PySide6/QML: Fix Qt properties of type QAbstractItemModelFriedemann Kleint2024-06-261-1/+2
| | | | | | | | | | | Add a metatype registration for the class for them to work. [ChangeLog][PySide6] Properties of type QAbstractItemModel can now be used in QML. Pick-to: 6.7 Change-Id: I3c0c08175a09f1decb00726b65edc73746fa71a7 Reviewed-by: Adrian Herrmann <adrian.herrmann@qt.io>
* Potential fix for crash currentOpcode_Is_CallMethNoArgs()Friedemann Kleint2024-06-261-0/+2
| | | | | | | | | | | | | PyEval_GetFrame() has been observed to return 0 in some cases; add a check. Amends f92b7dcac9537fb091dc15d3ee218f1984d8abef. Task-number: PYSIDE-1735 Fixes: PYSIDE-2796 Pick-to: 6.7 6.5 Change-Id: I403b0483a2654c20192e5554c86d5170188702d9 Reviewed-by: Christian Tismer <tismer@stackless.com> Reviewed-by: Adrian Herrmann <adrian.herrmann@qt.io>
* shiboken6: Prevent converter name clashes between classes and partially ↵Friedemann Kleint2024-06-2610-7/+85
| | | | | | | | | | | | | | | | | | | | | qualified aliases Change the behavior of registerConverterName() to always overwrite existing entries. It should then only be used for fully qualified names. Add a function registerConverterAlias() which does not overwrite existing entries for registering partially qualified names. Use registerConverterAlias() for the primitive types since they are re-registered in multiple modules. This prevents clashes when registering duplicate classes. For example, registering a globally scoped class "Connection" will then overwrite the partially qualified alias "Connection" of "QMetaObject::Connection". Fixes: PYSIDE-2792 Change-Id: I2bd3c0bff96da6d3ceddd46a2368fe6b94bbed68 Reviewed-by: Christian Tismer <tismer@stackless.com>
* shiboken6: Refactor registerConverterName() streamable helperFriedemann Kleint2024-06-263-58/+111
| | | | | | | | | | | | | Move the functionality to register partially qualified names (previously in helper registerConverterInScopes() and elsewhere), to register names with indirections, and to use typeid() into the streamable class controlled by flags. Simplify the code accordingly. This requires adding indexOf() to the helpers for QAnyStringView. Task-number: PYSIDE-2792 Change-Id: I7af0d8333e3c417e03f6615b471dc7220c95d388 Reviewed-by: Christian Tismer <tismer@stackless.com>
* shiboken6: Do not re-register a smart pointer converter under the pointee ↵Friedemann Kleint2024-06-251-2/+0
| | | | | | | | | | | | | type name Invoking them would crash. They don't have any effect anyways since registerConverterName() ignores existing names. Amends 465587ffbac4c7f7b8b6a2219661e42939cb15f3. Task-number: PYSIDE-454 Task-number: PYSIDE-2792 Change-Id: Idcb9d9b4c8f89ef84047f98ae1f7d627bf3ff5be Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* shiboken6: Fix clang-tidy warning about using std::any_of instead of loopsFriedemann Kleint2024-06-246-151/+146
| | | | | Change-Id: Ic85973e29870456bf422a3ac75fd9d68524ad886 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* libpyside: Add explanatory comment about methodsFriedemann Kleint2024-06-241-2/+6
| | | | | | Pick-to: 6.7 Change-Id: I0731c9c02de928dcdf268f5fc773148363b9a8fe Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* libpysideqml: Fix static analysis warningsFriedemann Kleint2024-06-246-19/+21
| | | | | | | | | | | - Initialize variables - Use auto * - Use nullptr - Remove repeated return types - Minor cleanups Change-Id: I26cacce81a4c8ebc885f8c34d59fdac5d0026af9 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* libpyside: Fix static analysis warningsFriedemann Kleint2024-06-2418-165/+175
| | | | | | | | | | | | | | | | - Initialize variables - Use auto * - Remove repeated return types - Fix else after return - Fix some invocations of static methods - Make functions const/static where appropriate - Fix some int types to avoid lossy conversions - Use Py_RETURN_NONE where appropriate - Minor cleanups - Remove some macros Change-Id: I7fa7a29e7b3dc47037027978001824e0709d001f Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* shiboken6: Fix static analysis warningsFriedemann Kleint2024-06-2440-163/+155
| | | | | | | | | | | | | | | | | | - Initialize variables - Use auto * - Use const references to prevent copies - Remove const from function returns - Remove repeated return types - Fix else after return/throw - Make functions const/static where appropriate - Add missing override - Fix some invocations of static methods - Fix some int types (qsizetype) to avoid lossy conversions - Minor cleanups - Remove some macros Change-Id: I414b8451703b136f135383289de49e743e84fb3a Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* Fix flake8 and typing issuesAdrian Herrmann2024-06-212-2/+2
| | | | | | | | | Fix a number of miscellaneous flake8 and typing issues exposed after updating to the modern typing syntax from 3.10 onwards. Task-number: PYSIDE-2786 Change-Id: I5476d1208dd1da3fa93bdec02bc6124a80b247fc Reviewed-by: Christian Tismer <tismer@stackless.com>
* Coin: Add support for Android wheelsSimo Fält2024-06-211-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - Split coin instructions into separate files specifically for Desktop, Android and common instructions - Make changes to cross_compilation script to support coin. - new 'coin' cli argument introduced. This is required because Qt installation from CI servers differ from the Qt installation from the maintenance tool. - Add a shell script to override the Python used for cross-compilation for the macOS 13 x86_64 system. This system is responsible for building the arm64 Android wheels. The system by default uses Python 3.10. However, python-for-android requires Python 3.11. Hence, we manually install python 3.11 into a non default path and use it for cross-compilation. The default Python of the aforementioned system has been updated to 3.11, but system still uses qt5#6.7. Hence it is not reflected yet. When ac72bb1d489f7442fe8d9aa168298a94ff62d941 is merged, we will finally get 3.11 and the need for this script can be removed. - Add markupsafe==2.0.1 to the requirements.txt file. This is required to prevent an error while installing Jinja2. ToDo: Tag Jinja2 version so that this requirements can possibly be removed. - Currently only x86_64 and arm64 wheels are produced since they are the most important. Most Android devices these days are arm64. This can be expanded to also include x86, but armv7 requires a Windows host and that is currently not possible with the CI. For armv7 wheels, users will have to build the wheels themselves using the provided cross compilation Python script. Task-number: PYSIDE-1612 Task-number: PYSIDE-2766 Change-Id: I8f15a85887e207a5c6605fd8696d15b4646fb2fd Reviewed-by: Simo Fält <simo.falt@qt.io>
* Use modern typing syntaxAdrian Herrmann2024-06-2013-76/+70
| | | | | | | | | | | | We can already use the modern typing syntax introduced with Python 3.10 in 3.9 via future statement definitions, even before we raise the minimum Python version to 3.10. Note that direct expressions with "|" don't work yet. Task-number: PYSIDE-2786 Change-Id: Ie36c140fc960328322502ea29cf6868805a7c558 Reviewed-by: Christian Tismer <tismer@stackless.com>
* Python-3.10: Allow the new syntax for Python 3.9Christian Tismer2024-06-20816-0/+817
| | | | | | | | Add a future statement to all Python source files. Task-number: PYSIDE-2786 Change-Id: Icd6688c7795a9e16fdcaa829686d57792df27690 Reviewed-by: Adrian Herrmann <adrian.herrmann@qt.io>
* Add shibokenmodule dependency for all _pyi modulesŁukasz Patron2024-06-191-0/+4
| | | | | | | | | | | | | | When building on Fedora rawhide, we sometimes end up running generate_pyi.py script while shibokenmodule is still being built, resulting in the following error message: ImportError: (...)/Shiboken.cpython-313-x86_64-linux-gnu.so: file too short Pick-to: 6.7 Change-Id: I500679bf12e4ba5a820db6c7971f8cdb0012b965 Reviewed-by: Christian Tismer <tismer@stackless.com> Reviewed-by: Łukasz Patron <priv.luk@gmail.com>
* QtAsyncio: Clarify usage of singleShot w/o contextAdrian Herrmann2024-06-181-1/+4
| | | | | | | | | | | The singleShot overload that accepts a context argument was used inside the do() method of the QAsyncioExecutorWrapper class, but this usage was unnecessary and adds confusion. Task-number: PYSIDE-769 Change-Id: Idcdd99eda6ae3bfd11ec50b9a42ff15ade005cc9 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> Reviewed-by: Christian Tismer <tismer@stackless.com>
* Qt Designer plugin: Remove Python version checkFriedemann Kleint2024-06-181-16/+22
| | | | | | | | | | Pre 3.8 is no longer supported. Move the code into a static helper for macOS only. This also fixes analyzer warnings about ignoring return codes. Pick-to: 6.7 Change-Id: Idd1a53729152f132958f94d288c13ac4399b6c78 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* libshiboken: Use enumeration instead of macros for type constantsFriedemann Kleint2024-06-181-20/+22
| | | | | | | | Fixes a static analysis warning about using macros and makes it consistent with the generated code. Change-Id: Ia5ea094e4e41a622d409f25c69492682d08f1c52 Reviewed-by: Christian Tismer <tismer@stackless.com>
* libshiboken: Fix some static analysis warningsFriedemann Kleint2024-06-1817-99/+88
| | | | | | | | | | | | - Initialize variables - Use auto * - Use range-based for - Move '#include "sbktypefactory.h"' from basewrapper.h to shiboken.h (for use by the generated code) - Fix some int types (Py_ssize_t/size_t) to avoid lossy conversions Change-Id: I7cc8b33850afcd07cc8f9a115e56a77cbacd58b0 Reviewed-by: Christian Tismer <tismer@stackless.com>
* Fix some documentation warnings and broken linksFriedemann Kleint2024-06-172-11/+11
| | | | | | Pick-to: 6.7 Change-Id: I5fbc1be390c7d24ef7f204721cd060e5d61c88e0 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
* Nuitka Deployment Doc - remove non-relevant sectionShyamnath Premnadh2024-06-171-13/+0
| | | | | | | | | - Not relevant with the latest Nuitka version that we use with pyside6-deploy Pick-to: 6.7 6.5 6.2 Change-Id: Id3e9cc5bcad678cb00a1b6049c740c5e321fbdde Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* Deployment Docs: Add instructions to generate a bug reportShyamnath Premnadh2024-06-172-2/+26
| | | | | | | | | | - Additionally, remove some comments from default.spec that are not relevant anymore. Pick-to: 6.7 Task-number: PYSIDE-1612 Change-Id: Iea2fed95507b6e649285e409cf8678287bf15a56 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* Desktop Deployment: Fix errorShyamnath Premnadh2024-06-171-7/+8
| | | | | | | | | | | | | | | In the scenario where 'pyside6-deploy --init' is used on the first run and for the consequent invocations, only running just 'pyside6-deploy' without any additional options, the deployment should have worked. This currently had a bug where it overrides the main Python entrypoint file with the default option of 'main.py'. This issue is caused due to the order of 'if' loop in the changed function. Pick-to: 6.7 Task-number: PYSIDE-1612 Change-Id: I605c4b9ff2035e85c0b5f73049a3ecc84d0fd80c Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* Android Deployment: Enable pyside6-android-deploy in macOSShyamnath Premnadh2024-06-143-4/+12
| | | | | | | | | | - enable the tool for macOS - add dependency .xml to the Android wheels Pick-to: 6.7 Task-number: PYSIDE-2766 Change-Id: I77495466b8a9cc3565c640beac202d533ee1d2a6 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* Desktop deployment: fix --modeShyamnath Premnadh2024-06-131-1/+1
| | | | | | | | | | Amends 32e353e9d91f45c23dcb07b0798237c79795cf0a Pick-to: 6.7 Task-number: PYSIDE-1612 Task-number: PYSIDE-2622 Change-Id: If14d53e5547d2f91d6cdad6a3460a50b375cdd9f Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* shiboken6: Fix an ASAN leak in traverseFunction()Friedemann Kleint2024-06-123-74/+69
| | | | | | | | | | Return a shared ptr to function from AbstractMetaBuilderPrivate::traverseFunction(), avoiding leaks when a function is not used. Pick-to: 6.7 Change-Id: I2fd215a25301fa6773f589bb3f085cf4c1febdd7 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* Do the transition to Python 3.13, GIL-partChristian Tismer2024-06-123-19/+52
| | | | | | | | | | | | | * opcodes have changed numbers. That made "import *" etc. fail. * PUSH_NULL is sometimes inserted before a call. * enum_test needed an overhaul due to opcode changes. Python 3.13 works fine. Supporting --disable-gil is a different issue. Task-number: PYSIDE-2751 Change-Id: I37b447148787e2923a58c091a5c8ac808d579bc0 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* Desktop Deployment: Update Nuitka to 2.3.2Shyamnath Premnadh2024-06-113-3/+6
| | | | | | | | | | - Full support for Python 3.12 - Experiemental support for Python 3.13 Pick-to: 6.7 Task-number: PYSIDE-1612 Change-Id: Ib4699351ec4105de756b4ac16cd7b3a49054a614 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* Shiboken: Fix a potential refcounting bug in Lazy InitChristian Tismer2024-06-101-2/+3
| | | | | | | | | | | | Keeping a reference to the original import function is needed in case someone else modifies import, too. Thanks to Tony Roberts for this finding. Change-Id: I6c362698e86e57b1a27cdd9367a89705e944825f Fixes: PYSIDE-2780 Pick-to: 6.7 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* Desktop Deployment: Enable Nuitka --standalone modeShyamnath Premnadh2024-06-107-13/+78
| | | | | | | | | | | | | - enables the standalone mode of Nuitka for pyside6-deploy - the mode can be set either through the command line or the config file - adapt tests - update documentation Pick-to: 6.7 Fixes: PYSIDE-2622 Task-number: PYSIDE-1612 Change-Id: I5a10c857d3e79174d2643139eb2e4f7b5e10d955 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* Fix non-unity buildFriedemann Kleint2024-06-103-0/+3
| | | | | | | | | | | | Amends c7c7dc9ba6da83f26d2ecda33a9af58d3f8f5f20, 11afd18d34c17a345315d226b6124dc1fd31d12c and 28d04cae204881392ddc0826a570d05ba82c5ee0. Pick-to: 6.7 Task-number: PYSIDE-2404 Task-number: PYSIDE-2768 Change-Id: I7caed5c4bddfaa594dfb692d5e087e0c88208e3e Reviewed-by: Christian Tismer <tismer@stackless.com>
* Lazy Load: Fix smart pointers with converters to smart pointers to pointee baseFriedemann Kleint2024-06-073-21/+5
| | | | | | | | | | | | | Smart pointers for which additional conversions to smart pointers to base classes of the pointee were registered after the type creation caused a crash with the lazy loading since getConverter() returned 0. Move these functions into the wrapper source and register them from the type creation functions. Task-number: PYSIDE-2404 Change-Id: I5f151748018c9cd84487ca92dee9cf4a42f7e4a7 Reviewed-by: Christian Tismer <tismer@stackless.com>
* shiboken: Fix a warning crash that is present in Python 3.13Christian Tismer2024-06-071-0/+3
| | | | | | | | | | | | This problem is new shown in Python 3.13 although this was not correct before. We need to remove the error before issuing a warning. Task-number: PYSIDE-2751 Change-Id: Ie4572e043388ca3f87092ea886e935b583f871b4 Pick-to: 6.7 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* shiboken6: Refactor writing the init functions into the module sourceFriedemann Kleint2024-06-072-18/+25
| | | | | | | | Split writeInitFunc() into 2 functions for declaration/call. Task-number: PYSIDE-2404 Change-Id: I173782409dd8dae3ae8f9eea474198a8f600ce06 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
* Lazy Load: Disable lazy for PyPyFriedemann Kleint2024-06-071-2/+13
| | | | | | | | Pick-to: 6.7 Task-number: PYSIDE-535 Task-number: PYSIDE-2404 Change-Id: I6d05e73457de7d12213bf9b046359355fcb0a941 Reviewed-by: Christian Tismer <tismer@stackless.com>
* Lazy Load: Fix crash caused by global enumerations in samplebindingFriedemann Kleint2024-06-072-1/+2
| | | | | | | | | Ensure PyEnumModule is set. Pick-to: 6.7 Task-number: PYSIDE-2404 Change-Id: Ie7b127129eba583a02e3b2d33ae640cea84bfb59 Reviewed-by: Christian Tismer <tismer@stackless.com>
* shiboken6: Make it possible to create smart pointer names in the global ↵Friedemann Kleint2024-06-077-2/+48
| | | | | | | | | | | namespace Previously, named instances of smart pointers from the std namespace would always end up in namespace std, too. Make it possible to prefix the names by "::", indicating global namespace. Change-Id: I45d7d7defa156730ed80c4b21bcc3c515b5ece74 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
* shiboken6: Do not write duplicated license commentFriedemann Kleint2024-06-071-3/+0
| | | | | | | | The license is already at the top of the header, no need to repeat it above the wrapper class declaration. Change-Id: I20fcfd57ca0afa635c2c4d4b6d37fd2e5caf4b85 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>