diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6abd35f..bf04ff6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/MANIFEST.in b/MANIFEST.in index cf221c5..3732228 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,9 @@ graft obniz/obniz graft obniz/parts + +# documentation assets under obniz/parts have no runtime purpose -- +# excluding them keeps the wheel small (photos/GIFs alone are ~13MB) +global-exclude *.jpg *.jpeg *.png *.gif *.fzz +recursive-exclude obniz/parts index.json +recursive-exclude obniz/parts README.md README-ja.md +global-exclude __pycache__ *.py[cod] diff --git a/Pipfile b/Pipfile index 79575ba..f935054 100644 --- a/Pipfile +++ b/Pipfile @@ -7,15 +7,14 @@ name = "pypi" test = "pytest -vv" lint = "sh -c 'flake8 && pipenv run format --check'" format = "black obniz/ tests/ " -build = "sh -c 'rm -rf build/ dist/ obniz.egg-info/ && python setup.py sdist bdist_wheel'" +build = "sh -c 'rm -rf build/ dist/ obniz.egg-info/ && python -m build'" testsubmit = "twine upload --repository testpypi dist/*" # no shortcut for production submit for safe [packages] -pyee = "==6.0.0" -websockets = ">=12,<14" -attrdict3 = "==2.0.2" -semver = "==2.8.1" +pyee = "==13.0.1" +websockets = ">=14.2,<16" +semver = "==3.0.4" [dev-packages] # "black" requires python 3.6+ @@ -30,6 +29,7 @@ pep8-naming = "*" pytest = "*" pytest-mock = "*" pyyaml = "*" +build = "*" setuptools = "*" wheel = "*" twine = "*" diff --git a/Pipfile.lock b/Pipfile.lock index dc05ba8..79a349d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "8ec6877aaef86f34ec835dfbb181b916c7b85a9a4af47e1a075cdd4c71da536c" + "sha256": "f49b86c142c03c44d8ceef2df8f799023058d169b0ab462186cbab59b3fe7935" }, "pipfile-spec": 6, "requires": {}, @@ -14,130 +14,107 @@ ] }, "default": { - "attrdict3": { - "hashes": [ - "sha256:004c171ca1120cc1755701db99d7fa4944afb1e68950434efdaa542513335fe8", - "sha256:a98b72de6a3f20b0997cc7efbba3555af6558ed9a97de4468a3f81cac11595dc" - ], - "index": "pypi", - "version": "==2.0.2" - }, "pyee": { "hashes": [ - "sha256:a9c9b60e8693a260dd942ef5a71358cfcbba15792d5e72caf0e3c891c4e91c3b", - "sha256:dbe44f61c40a995d2bdfd83d9fcb87ae025882d2c7f366513325e3daa09d7ede" + "sha256:0b931f7c14535667ed4c7e0d531716368715e860b988770fc7eb8578d1f67fc8", + "sha256:af2f8fede4171ef667dfded53f96e2ed0d6e6bd7ee3bb46437f77e3b57689228" ], "index": "pypi", - "version": "==6.0.0" + "markers": "python_version >= '3.8'", + "version": "==13.0.1" }, "semver": { "hashes": [ - "sha256:41c9aa26c67dc16c54be13074c352ab666bce1fa219c7110e8f03374cd4206b0", - "sha256:5b09010a66d9a3837211bb7ae5a20d10ba88f8cb49e92cb139a69ef90d5060d8" + "sha256:9c824d87ba7f7ab4a1890799cec8596f15c1241cb473404ea1cb0c55e4b04746", + "sha256:afc7d8c584a5ed0a11033af086e8af226a9c0b206f313e0301f8dd7b6b589602" ], "index": "pypi", - "version": "==2.8.1" + "markers": "python_version >= '3.7'", + "version": "==3.0.4" }, - "six": { + "typing-extensions": { "hashes": [ - "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", - "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" + "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", + "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", - "version": "==1.17.0" + "markers": "python_version >= '3.9'", + "version": "==4.16.0" }, "websockets": { "hashes": [ - "sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a", - "sha256:035233b7531fb92a76beefcbf479504db8c72eb3bff41da55aecce3a0f729e54", - "sha256:149e622dc48c10ccc3d2760e5f36753db9cacf3ad7bc7bbbfd7d9c819e286f23", - "sha256:163e7277e1a0bd9fb3c8842a71661ad19c6aa7bb3d6678dc7f89b17fbcc4aeb7", - "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135", - "sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700", - "sha256:204e5107f43095012b00f1451374693267adbb832d29966a01ecc4ce1db26faf", - "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5", - "sha256:25c35bf84bf7c7369d247f0b8cfa157f989862c49104c5cf85cb5436a641d93e", - "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c", - "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02", - "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a", - "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418", - "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f", - "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3", - "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68", - "sha256:4059f790b6ae8768471cddb65d3c4fe4792b0ab48e154c9f0a04cefaabcd5978", - "sha256:459bf774c754c35dbb487360b12c5727adab887f1622b8aed5755880a21c4a20", - "sha256:463e1c6ec853202dd3657f156123d6b4dad0c546ea2e2e38be2b3f7c5b8e7295", - "sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b", - "sha256:485307243237328c022bc908b90e4457d0daa8b5cf4b3723fd3c4a8012fce4c6", - "sha256:48a2ef1381632a2f0cb4efeff34efa97901c9fbc118e01951ad7cfc10601a9bb", - "sha256:4b889dbd1342820cc210ba44307cf75ae5f2f96226c0038094455a96e64fb07a", - "sha256:586a356928692c1fed0eca68b4d1c2cbbd1ca2acf2ac7e7ebd3b9052582deefa", - "sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0", - "sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a", - "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238", - "sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c", - "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084", - "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19", - "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d", - "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7", - "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9", - "sha256:6d2aad13a200e5934f5a6767492fb07151e1de1d6079c003ab31e1823733ae79", - "sha256:6d6855bbe70119872c05107e38fbc7f96b1d8cb047d95c2c50869a46c65a8e96", - "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6", - "sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe", - "sha256:7a43cfdcddd07f4ca2b1afb459824dd3c6d53a51410636a2c7fc97b9a8cf4842", - "sha256:7bd6abf1e070a6b72bfeb71049d6ad286852e285f146682bf30d0296f5fbadfa", - "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3", - "sha256:7c65ffa900e7cc958cd088b9a9157a8141c991f8c53d11087e6fb7277a03f81d", - "sha256:80c421e07973a89fbdd93e6f2003c17d20b69010458d3a8e37fb47874bd67d51", - "sha256:82d0ba76371769d6a4e56f7e83bb8e81846d17a6190971e38b5de108bde9b0d7", - "sha256:83f91d8a9bb404b8c2c41a707ac7f7f75b9442a0a876df295de27251a856ad09", - "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096", - "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9", - "sha256:9156c45750b37337f7b0b00e6248991a047be4aa44554c9886fe6bdd605aab3b", - "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5", - "sha256:95858ca14a9f6fa8413d29e0a585b31b278388aa775b8a81fa24830123874678", - "sha256:95df24ca1e1bd93bbca51d94dd049a984609687cb2fb08a7f2c56ac84e9816ea", - "sha256:9b37c184f8b976f0c0a231a5f3d6efe10807d41ccbe4488df8c74174805eea7d", - "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49", - "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc", - "sha256:9ef8aa8bdbac47f4968a5d66462a2a0935d044bf35c0e5a8af152d58516dbeb5", - "sha256:a11e38ad8922c7961447f35c7b17bffa15de4d17c70abd07bfbe12d6faa3e027", - "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0", - "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878", - "sha256:a569eb1b05d72f9bce2ebd28a1ce2054311b66677fcd46cf36204ad23acead8c", - "sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa", - "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f", - "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6", - "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2", - "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf", - "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708", - "sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6", - "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f", - "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd", - "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2", - "sha256:c7934fd0e920e70468e676fe7f1b7261c1efa0d6c037c6722278ca0228ad9d0d", - "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7", - "sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f", - "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5", - "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6", - "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557", - "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14", - "sha256:d8dbb1bf0c0a4ae8b40bdc9be7f644e2f3fb4e8a9aca7145bfa510d4a374eeb7", - "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd", - "sha256:deeb929efe52bed518f6eb2ddc00cc496366a14c726005726ad62c2dd9017a3c", - "sha256:df01aea34b6e9e33572c35cd16bae5a47785e7d5c8cb2b54b2acdb9678315a17", - "sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23", - "sha256:e4450fc83a3df53dec45922b576e91e94f5578d06436871dce3a6be38e40f5db", - "sha256:e54affdeb21026329fb0744ad187cf812f7d3c2aa702a5edb562b325191fcab6", - "sha256:e9875a0143f07d74dc5e1ded1c4581f0d9f7ab86c78994e2ed9e95050073c94d", - "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9", - "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee", - "sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6" + "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2", + "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9", + "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5", + "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", + "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", + "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e", + "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", + "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256", + "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85", + "sha256:2034693ad3097d5355bfdacfffcbd3ef5694f9718ab7f29c29689a9eae841880", + "sha256:21c1fa28a6a7e3cbdc171c694398b6df4744613ce9b36b1a498e816787e28123", + "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", + "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065", + "sha256:363c6f671b761efcb30608d24925a382497c12c506b51661883c3e22337265ed", + "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41", + "sha256:3b1ac0d3e594bf121308112697cf4b32be538fb1444468fb0a6ae4feebc83411", + "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597", + "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", + "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c", + "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3", + "sha256:47819cea040f31d670cc8d324bb6435c6f133b8c7a19ec3d61634e62f8d8f9eb", + "sha256:47b099e1f4fbc95b701b6e85768e1fcdaf1630f3cbe4765fa216596f12310e2e", + "sha256:4a9fac8e469d04ce6c25bb2610dc535235bd4aa14996b4e6dbebf5e007eba5ee", + "sha256:4b826973a4a2ae47ba357e4e82fa44a463b8f168e1ca775ac64521442b19e87f", + "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf", + "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf", + "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", + "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a", + "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665", + "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", + "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", + "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4", + "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d", + "sha256:5f4c04ead5aed67c8a1a20491d54cdfba5884507a48dd798ecaf13c74c4489f5", + "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65", + "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792", + "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", + "sha256:67f2b6de947f8c757db2db9c71527933ad0019737ec374a8a6be9a956786aaf9", + "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3", + "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", + "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", + "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", + "sha256:7f493881579c90fc262d9cdbaa05a6b54b3811c2f300766748db79f098db9940", + "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", + "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", + "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413", + "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8", + "sha256:a625e06551975f4b7ea7102bc43895b90742746797e2e14b70ed61c43a90f09b", + "sha256:abdc0c6c8c648b4805c5eacd131910d2a7f6455dfd3becab248ef108e89ab16a", + "sha256:ac017dd64572e5c3bd01939121e4d16cf30e5d7e110a119399cf3133b63ad054", + "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb", + "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205", + "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", + "sha256:b7643a03db5c95c799b89b31c036d5f27eeb4d259c798e878d6937d71832b1e4", + "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", + "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9", + "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", + "sha256:d08eb4c2b7d6c41da6ca0600c077e93f5adcfd979cd777d747e9ee624556da4b", + "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", + "sha256:d591f8de75824cbb7acad4e05d2d710484f15f29d4a915092675ad3456f11770", + "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe", + "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b", + "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562", + "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", + "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215", + "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", + "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", + "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", + "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==13.1" + "markers": "python_version >= '3.9'", + "version": "==15.0.1" } }, "develop": { @@ -149,13 +126,22 @@ "markers": "python_version >= '3.9'", "version": "==26.1.0" }, + "build": { + "hashes": [ + "sha256:13f3eecb844759ab66efec90ca17639bbf14dc06cb2fdf37a9010322d9c50a6f", + "sha256:302c22c3ba2a0fd5f3911918651341ebb3896176cbdec15bd421f80b1afc7647" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==1.5.0" + }, "cachetools": { "hashes": [ - "sha256:0def7134eba79e59448edaf5d2e3cc8e49978ab2fd56189c1efd19856b134ab5", - "sha256:900cda61ff34fafca2b7f78cfd2a91e2d4f9655c19309ef542ce0a04f91e6cd9" + "sha256:2c12e255780330af28b91bb7fb96cce4c766f04e38396b9a24510190a5827096", + "sha256:c7a79e7f30ba9943c1cefd08cc36f006aaae086e017af9166f1d59d6170c47e1" ], "markers": "python_version >= '3.10'", - "version": "==7.1.5" + "version": "==7.1.6" }, "certifi": { "hashes": [ @@ -515,6 +501,14 @@ "markers": "python_version >= '3.10'", "version": "==1.11.0" }, + "pyproject-hooks": { + "hashes": [ + "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", + "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913" + ], + "markers": "python_version >= '3.7'", + "version": "==1.2.0" + }, "pytest": { "hashes": [ "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", diff --git a/README-ja.md b/README-ja.md index deda5ca..14c2efd 100644 --- a/README-ja.md +++ b/README-ja.md @@ -5,7 +5,7 @@ [obniz](https://obniz.io/)をpythonから操作するためのsdkです。 [obnizBoard](https://obniz.io/ja/doc/obniz_board_hobby_90/hw_overview)と[obnizOS](https://obniz.io/ja/doc/obnizos/os_overview)に対応しています -**Python 3.8以上**で動作します。 +**Python 3.9以上**で動作します。 diff --git a/README.md b/README.md index eb3b67f..ed46aac 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Control obniz from python. This sdk works with [obniz api](https://obniz.io/doc/about_obniz_api). -Compatible with **Python 3.8+**. +Compatible with **Python 3.9+**. diff --git a/obniz/obniz/__version__.py b/obniz/obniz/__version__.py index 49e0fc1..777f190 100644 --- a/obniz/obniz/__version__.py +++ b/obniz/obniz/__version__.py @@ -1 +1 @@ -__version__ = "0.7.0" +__version__ = "0.8.0" diff --git a/obniz/obniz/libs/embeds/ble/ble_attribute_abstract.py b/obniz/obniz/libs/embeds/ble/ble_attribute_abstract.py index 05fc3ae..de7fcc8 100644 --- a/obniz/obniz/libs/embeds/ble/ble_attribute_abstract.py +++ b/obniz/obniz/libs/embeds/ble/ble_attribute_abstract.py @@ -1,4 +1,4 @@ -from pyee import AsyncIOEventEmitter +from pyee.asyncio import AsyncIOEventEmitter from .ble_helper import BleHelper from ...utils.eventloop import get_event_loop diff --git a/obniz/obniz/libs/embeds/ble/ble_remote_peripheral.py b/obniz/obniz/libs/embeds/ble/ble_remote_peripheral.py index d1e7072..221f29b 100644 --- a/obniz/obniz/libs/embeds/ble/ble_remote_peripheral.py +++ b/obniz/obniz/libs/embeds/ble/ble_remote_peripheral.py @@ -1,6 +1,6 @@ import json -from pyee import AsyncIOEventEmitter +from pyee.asyncio import AsyncIOEventEmitter from .ble_helper import BleHelper from .ble_remote_service import BleRemoteService diff --git a/obniz/obniz/libs/embeds/ble/ble_scan.py b/obniz/obniz/libs/embeds/ble/ble_scan.py index d139c0c..331f914 100644 --- a/obniz/obniz/libs/embeds/ble/ble_scan.py +++ b/obniz/obniz/libs/embeds/ble/ble_scan.py @@ -1,4 +1,4 @@ -from pyee import AsyncIOEventEmitter +from pyee.asyncio import AsyncIOEventEmitter from .ble_helper import BleHelper diff --git a/obniz/obniz/libs/embeds/ble/ble_security.py b/obniz/obniz/libs/embeds/ble/ble_security.py index aaf6a39..009a25f 100644 --- a/obniz/obniz/libs/embeds/ble/ble_security.py +++ b/obniz/obniz/libs/embeds/ble/ble_security.py @@ -1,4 +1,4 @@ -from pyee import AsyncIOEventEmitter +from pyee.asyncio import AsyncIOEventEmitter import semver class BleSecurity: @@ -51,7 +51,7 @@ def set_mode_level(self, mode, level): raise Exception(msg) def check_introduced_firmware(self, introduced_version, function_name): - res = semver.match(self.obniz.firmware_ver, "<=" + introduced_version) + res = semver.Version.parse(self.obniz.firmware_ver).match("<=" + introduced_version) if res: msg = ( "{} is available ".format(function_name) + diff --git a/obniz/obniz/libs/embeds/storage.py b/obniz/obniz/libs/embeds/storage.py index 3cccb4d..06d3ef8 100644 --- a/obniz/obniz/libs/embeds/storage.py +++ b/obniz/obniz/libs/embeds/storage.py @@ -66,7 +66,7 @@ def _require_firmware_major(self, major): if not fw: raise Exception("unknown obniz firmware version. connect first") - if semver.parse_version_info(fw).major < major: + if semver.Version.parse(fw).major < major: raise Exception( "Please update obniz firmware >= {}.0.0".format(major) ) diff --git a/obniz/obniz/libs/io_peripherals/spi.py b/obniz/obniz/libs/io_peripherals/spi.py index a8469e0..0cdbfe4 100644 --- a/obniz/obniz/libs/io_peripherals/spi.py +++ b/obniz/obniz/libs/io_peripherals/spi.py @@ -90,7 +90,7 @@ def write_wait(self, data): if not self.used: raise Exception("spi{} is not started".format(self.id)) - if semver.match(self.obniz.firmware_ver, "<=1.0.2") and len(data) > 32: + if semver.Version.parse(self.obniz.firmware_ver).match("<=1.0.2") and len(data) > 32: raise Exception( "with your obniz " + self.obniz.firmware_ver @@ -110,7 +110,7 @@ def write_wait(self, data): def write(self, data): if not self.used: raise Exception("spi{0} is not started".format(self.id)) - if semver.match(self.obniz.firmware_ver, "<=1.0.2") and len(data) > 32: + if semver.Version.parse(self.obniz.firmware_ver).match("<=1.0.2") and len(data) > 32: raise Exception( "with your obniz {0}. spi max length=32byte but yours {1}. Please update obniz firmware".format( self.obniz.firmware_ver, len(data) diff --git a/obniz/obniz/libs/plugin/plugin.py b/obniz/obniz/libs/plugin/plugin.py index 79f614d..f94609d 100644 --- a/obniz/obniz/libs/plugin/plugin.py +++ b/obniz/obniz/libs/plugin/plugin.py @@ -117,14 +117,14 @@ def _require_firmware(self, version): if not fw: raise Exception("unknown obniz firmware version. connect first") - info = semver.parse_version_info(fw) + info = semver.Version.parse(fw) if version == "7.1.0": # accept prereleases like 7.1.0-beta.0, as obniz.js does ok = info.major > 7 or (info.major == 7 and info.minor >= 1) elif version == "7.0.0": ok = info.major >= 7 else: - ok = not semver.match(fw, "<" + version) + ok = not info.match("<" + version) if not ok: raise Exception("Please update obniz firmware >= " + version) diff --git a/obniz/obniz/libs/utils/attr_default.py b/obniz/obniz/libs/utils/attr_default.py new file mode 100644 index 0000000..868f9a8 --- /dev/null +++ b/obniz/obniz/libs/utils/attr_default.py @@ -0,0 +1,39 @@ +class AttrDefault(dict): + """In-repo replacement for the abandoned attrdict package's AttrDefault. + + A dict whose keys are also readable/writable as attributes, and whose + missing keys yield default_factory() (stored, like collections.defaultdict) + instead of raising. Parts rely on all three behaviors, e.g. + ``self.params.mode = self.params.mode or 'master'``. + """ + + def __init__(self, default_factory=bool, items=None): + super().__init__(items if items is not None else {}) + object.__setattr__(self, "_default_factory", default_factory) + + def __getitem__(self, key): + if key not in self: + default = self._default_factory() + super().__setitem__(key, default) + return default + return super().__getitem__(key) + + def __getattr__(self, key): + if key.startswith("__"): + raise AttributeError(key) + return self[key] + + def __setattr__(self, key, value): + self[key] = value + + def __delattr__(self, key): + try: + del self[key] + except KeyError: + raise AttributeError(key) + + def get(self, key, default=None): + # do not auto-create on .get(), matching plain dict semantics + if key in self: + return dict.__getitem__(self, key) + return default diff --git a/obniz/obniz/libs/utils/util.py b/obniz/obniz/libs/utils/util.py index c976f8d..239e8ad 100644 --- a/obniz/obniz/libs/utils/util.py +++ b/obniz/obniz/libs/utils/util.py @@ -1,11 +1,10 @@ import json -import attrdict class ObnizUtil: @classmethod def _key_filter(cls, params, keys): filterd_params = {} - if type(params) not in [dict, attrdict.default.AttrDefault]: + if not isinstance(params, dict): return filterd_params for key in [key for key in params.keys() if key in keys]: @@ -15,7 +14,7 @@ def _key_filter(cls, params, keys): @classmethod def _required_keys(cls, params, keys): - if type(params) not in [dict, attrdict.default.AttrDefault]: + if not isinstance(params, dict): return keys[0] for key in keys: diff --git a/obniz/obniz/obniz_components.py b/obniz/obniz/obniz_components.py index 7eaa603..e158ab0 100644 --- a/obniz/obniz/obniz_components.py +++ b/obniz/obniz/obniz_components.py @@ -1,3 +1,5 @@ +import asyncio + from .libs.embeds.ble.ble import ObnizBLE from .libs.embeds.display import Display from .libs.embeds.storage import Storage @@ -16,9 +18,6 @@ from .obniz_connection import ObnizConnection from .obniz_parts import ObnizParts -import attrdict -import asyncio - class ObnizComponents(ObnizParts): def __init__(self, id, options): @@ -178,7 +177,7 @@ def get_free_i2c(self): return self._get_free_peripheral_unit('i2c') def get_i2c_with_config(self, config): - if type(config) not in [dict, attrdict.default.AttrDefault]: + if not isinstance(config, dict): raise Exception("get_i2c_with_config need config arg") if config.get("i2c"): return config.get("i2c") @@ -190,7 +189,7 @@ def get_free_spi(self): return self._get_free_peripheral_unit('spi') def get_spi_with_config(self, config): - if type(config) not in [dict, attrdict.default.AttrDefault]: + if not isinstance(config, dict): raise Exception("get_spi_with_config need config arg") if config.get("spi"): return config.get("spi") diff --git a/obniz/obniz/obniz_connection.py b/obniz/obniz/obniz_connection.py index 88b77c3..4345502 100644 --- a/obniz/obniz/obniz_connection.py +++ b/obniz/obniz/obniz_connection.py @@ -1,8 +1,9 @@ import inspect import json -from pyee import AsyncIOEventEmitter +from pyee.asyncio import AsyncIOEventEmitter import websockets +from websockets.protocol import State from .__version__ import __version__ from .libs.utils.eventloop import ensure_future, get_event_loop @@ -146,7 +147,7 @@ def wsconnect(self, desired_server): if desired_server: server = desired_server - if self.socket and self.socket.open: + if self._socket_open(self.socket): self.close() url = server + "/obniz/{}/ws/1".format(self.id) @@ -232,7 +233,7 @@ async def connecting(): def _disconnect_local(self): if self.socket_local: - if self.socket.open: + if self._socket_open(self.socket): self.socket_local.close() self.clear_socket(self.socket_local) @@ -273,8 +274,12 @@ def clear_socket(self, socket): # socket.onerror = null # } + @staticmethod + def _socket_open(socket): + return socket is not None and socket.state is State.OPEN + def connect(self): - if self.socket and self.socket.open: + if self._socket_open(self.socket): return self.wsconnect() @@ -283,7 +288,7 @@ def close(self): # self._drainQueued() self._disconnect_local() if self.socket: - if self.socket.open: + if self._socket_open(self.socket): # Connecting & Connected self.connection_state = 'closing' ensure_future(self.socket.close(1000, "close")) @@ -300,7 +305,7 @@ def _call_on_connect(self): self._wait_for_local_connect_ready_timer = None else: # obniz.js hasn't wait local_connect - if self.socket_local and self.socket.open: + if self.socket_local and self._socket_open(self.socket): # delayed connect should_call = False else: @@ -358,7 +363,7 @@ def _send_routed(self, data): ) return - if self.socket and self.socket.open: + if self._socket_open(self.socket): ensure_future(self.socket.send(data)) # if self.socket.buffered_amount > self.bufferd_amound_warn_bytes: # self.warning( diff --git a/obniz/obniz/obniz_parts.py b/obniz/obniz/obniz_parts.py index b9915a9..a302adf 100644 --- a/obniz/obniz/obniz_parts.py +++ b/obniz/obniz/obniz_parts.py @@ -1,7 +1,6 @@ -from attrdict import AttrDefault - -from .obniz_connection import ObnizConnection +from .libs.utils.attr_default import AttrDefault from .libs.utils.util import ObnizUtil +from .obniz_connection import ObnizConnection _parts = {} diff --git a/obniz/parts/Camera/ArduCAMMini/__init__.py b/obniz/parts/Camera/ArduCAMMini/__init__.py index e37a4db..ae518ca 100644 --- a/obniz/parts/Camera/ArduCAMMini/__init__.py +++ b/obniz/parts/Camera/ArduCAMMini/__init__.py @@ -1,8 +1,8 @@ -from attrdict import AttrDefault - import asyncio import base64 +from obniz.obniz.libs.utils.attr_default import AttrDefault + class ArduCAMMini: def __init__(self): self.keys = ['cs', 'mosi', 'miso', 'sclk', 'gnd', 'vcc', 'sda', 'scl', 'spi', 'i2c', 'spi_frequency', 'spi_drive'] diff --git a/obniz/parts/DistanceSensor/GP2Y0A21YK0F/__init__.py b/obniz/parts/DistanceSensor/GP2Y0A21YK0F/__init__.py index c099c0f..f057c76 100644 --- a/obniz/parts/DistanceSensor/GP2Y0A21YK0F/__init__.py +++ b/obniz/parts/DistanceSensor/GP2Y0A21YK0F/__init__.py @@ -1,8 +1,8 @@ -from attrdict import AttrDefault - import asyncio import math +from obniz.obniz.libs.utils.attr_default import AttrDefault + class GP2Y0A21YK0F: def __init__(self): self.keys = ['vcc', 'gnd', 'signal'] diff --git a/obniz/parts/DistanceSensor/HC-SR04/__init__.py b/obniz/parts/DistanceSensor/HC-SR04/__init__.py index 6e11537..ea97eb8 100644 --- a/obniz/parts/DistanceSensor/HC-SR04/__init__.py +++ b/obniz/parts/DistanceSensor/HC-SR04/__init__.py @@ -1,7 +1,6 @@ import math -from attrdict import AttrDefault - +from obniz.obniz.libs.utils.attr_default import AttrDefault from obniz.obniz.libs.utils.eventloop import get_event_loop diff --git a/obniz/parts/Light/LED/__init__.py b/obniz/parts/Light/LED/__init__.py index 15d3414..1a9ffe7 100644 --- a/obniz/parts/Light/LED/__init__.py +++ b/obniz/parts/Light/LED/__init__.py @@ -1,4 +1,4 @@ -from attrdict import AttrDefault +from obniz.obniz.libs.utils.attr_default import AttrDefault class LED: def __init__(self): diff --git a/obniz/parts/MovementSensor/Button/__init__.py b/obniz/parts/MovementSensor/Button/__init__.py index c5cd701..76dc935 100644 --- a/obniz/parts/MovementSensor/Button/__init__.py +++ b/obniz/parts/MovementSensor/Button/__init__.py @@ -1,5 +1,4 @@ -from attrdict import AttrDefault - +from obniz.obniz.libs.utils.attr_default import AttrDefault from obniz.obniz.libs.utils.eventloop import get_event_loop diff --git a/obniz/parts/MovementSensor/HC-SR505/__init__.py b/obniz/parts/MovementSensor/HC-SR505/__init__.py index ef99b14..89940c9 100644 --- a/obniz/parts/MovementSensor/HC-SR505/__init__.py +++ b/obniz/parts/MovementSensor/HC-SR505/__init__.py @@ -1,6 +1,7 @@ -from attrdict import AttrDefault import asyncio +from obniz.obniz.libs.utils.attr_default import AttrDefault + class HCSR505: def __init__(self): self.keys = ['vcc', 'gnd', 'signal'] diff --git a/obniz/parts/MovementSensor/JoyStick/__init__.py b/obniz/parts/MovementSensor/JoyStick/__init__.py index ab8a538..82563f3 100644 --- a/obniz/parts/MovementSensor/JoyStick/__init__.py +++ b/obniz/parts/MovementSensor/JoyStick/__init__.py @@ -1,7 +1,7 @@ -from attrdict import AttrDefault - import asyncio +from obniz.obniz.libs.utils.attr_default import AttrDefault + class JoyStick: def __init__(self): self.keys = ['sw', 'y', 'x', 'vcc', 'gnd', 'i2c'] diff --git a/obniz/parts/MovementSensor/KXR94-2050/__init__.py b/obniz/parts/MovementSensor/KXR94-2050/__init__.py index 20ebfaa..7439bfa 100644 --- a/obniz/parts/MovementSensor/KXR94-2050/__init__.py +++ b/obniz/parts/MovementSensor/KXR94-2050/__init__.py @@ -1,7 +1,7 @@ -from attrdict import AttrDefault - import asyncio +from obniz.obniz.libs.utils.attr_default import AttrDefault + class KXR942050: def __init__(self): self.keys = ['x', 'y', 'z', 'vcc', 'gnd', 'enable', 'self_test'] diff --git a/obniz/parts/MovementSensor/Potentiometer/__init__.py b/obniz/parts/MovementSensor/Potentiometer/__init__.py index 4b2a4c8..866ac1f 100644 --- a/obniz/parts/MovementSensor/Potentiometer/__init__.py +++ b/obniz/parts/MovementSensor/Potentiometer/__init__.py @@ -1,4 +1,4 @@ -from attrdict import AttrDefault +from obniz.obniz.libs.utils.attr_default import AttrDefault class Potentiometer: def __init__(self): diff --git a/obniz/parts/Moving/DCMotor/__init__.py b/obniz/parts/Moving/DCMotor/__init__.py index 89bdec3..e022150 100644 --- a/obniz/parts/Moving/DCMotor/__init__.py +++ b/obniz/parts/Moving/DCMotor/__init__.py @@ -1,4 +1,4 @@ -from attrdict import AttrDefault +from obniz.obniz.libs.utils.attr_default import AttrDefault class DCMotor: def __init__(self): diff --git a/obniz/parts/Moving/ServoMotor/__init__.py b/obniz/parts/Moving/ServoMotor/__init__.py index 2511359..305b8c6 100644 --- a/obniz/parts/Moving/ServoMotor/__init__.py +++ b/obniz/parts/Moving/ServoMotor/__init__.py @@ -1,4 +1,4 @@ -from attrdict import AttrDefault +from obniz.obniz.libs.utils.attr_default import AttrDefault class ServoMotor: def __init__(self): diff --git a/obniz/parts/Moving/StepperMotor/__init__.py b/obniz/parts/Moving/StepperMotor/__init__.py index 4ab9025..6be9a16 100644 --- a/obniz/parts/Moving/StepperMotor/__init__.py +++ b/obniz/parts/Moving/StepperMotor/__init__.py @@ -1,7 +1,7 @@ -from attrdict import AttrDefault - import asyncio +from obniz.obniz.libs.utils.attr_default import AttrDefault + class StepperMotor: def __init__(self): self.keys = ['a', 'b', 'aa', 'bb', 'common'] diff --git a/obniz/parts/PressureSensor/FSR-40X/__init__.py b/obniz/parts/PressureSensor/FSR-40X/__init__.py index dc16c31..f94363a 100644 --- a/obniz/parts/PressureSensor/FSR-40X/__init__.py +++ b/obniz/parts/PressureSensor/FSR-40X/__init__.py @@ -1,7 +1,7 @@ -from attrdict import AttrDefault - import asyncio +from obniz.obniz.libs.utils.attr_default import AttrDefault + class FSR40X: def __init__(self): self.keys = ['pin0', 'pin1'] diff --git a/obniz/parts/TemperatureSensor/analog/LM60/__init__.py b/obniz/parts/TemperatureSensor/analog/LM60/__init__.py index f9ad449..8c90b48 100644 --- a/obniz/parts/TemperatureSensor/analog/LM60/__init__.py +++ b/obniz/parts/TemperatureSensor/analog/LM60/__init__.py @@ -1,5 +1,5 @@ +from obniz.obniz.libs.utils.attr_default import AttrDefault from .. import AnalogTemplatureSensor -from attrdict import AttrDefault class LM60(AnalogTemplatureSensor): @staticmethod diff --git a/obniz/parts/TemperatureSensor/i2c/BME280/__init__.py b/obniz/parts/TemperatureSensor/i2c/BME280/__init__.py index 473bdda..975a021 100644 --- a/obniz/parts/TemperatureSensor/i2c/BME280/__init__.py +++ b/obniz/parts/TemperatureSensor/i2c/BME280/__init__.py @@ -1,7 +1,7 @@ import asyncio import math -from attrdict import AttrDefault +from obniz.obniz.libs.utils.attr_default import AttrDefault class BME280: def __init__(self): diff --git a/obniz/parts/TemperatureSensor/i2c/SHT31/__init__.py b/obniz/parts/TemperatureSensor/i2c/SHT31/__init__.py index 7304210..68b70be 100644 --- a/obniz/parts/TemperatureSensor/i2c/SHT31/__init__.py +++ b/obniz/parts/TemperatureSensor/i2c/SHT31/__init__.py @@ -1,7 +1,7 @@ -from attrdict import AttrDefault - import asyncio +from obniz.obniz.libs.utils.attr_default import AttrDefault + class SHT31: def __init__(self): self.required_keys = ['adr', 'addressmode'] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e3ed83e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,39 @@ +[build-system] +requires = ["setuptools>=64"] +build-backend = "setuptools.build_meta" + +[project] +name = "obniz" +description = "obniz sdk for python" +readme = "README.md" +authors = [{ name = "yukisato", email = "yuki@yuki-sato.com" }] +requires-python = ">=3.9" +dependencies = [ + "pyee==13.0.1", + "websockets>=14.2,<16", + "semver==3.0.4", +] +classifiers = [ + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Operating System :: OS Independent", +] +dynamic = ["version"] + +[project.urls] +Homepage = "https://obniz.io/" +Repository = "https://github.com/obniz/obniz-python-sdk" + +[tool.setuptools.dynamic] +version = { attr = "obniz.obniz.__version__.__version__" } + +[tool.setuptools.packages.find] +include = ["obniz*"] + +[tool.setuptools] +include-package-data = true diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 2dd08ee..0000000 --- a/pytest.ini +++ /dev/null @@ -1,6 +0,0 @@ -[pytest] -filterwarnings = - ; workaround for https://github.com/yaml/pyyaml/issues/202 - ignore:Using or importing the ABCs::yaml.constructor - ; workaround for https://github.com/aaugustin/websockets/issues/514 - ignore:'with \(yield from lock\)'::websockets.protocol diff --git a/setup.py b/setup.py deleted file mode 100644 index 120a83d..0000000 --- a/setup.py +++ /dev/null @@ -1,52 +0,0 @@ -import setuptools -from codecs import open -from os import path -import re - -package_name = "obniz" -root_dir = path.abspath(path.dirname(__file__)) - -with open("README.md", "r") as fh: - long_description = fh.read() - -with open(path.join(root_dir, package_name, '__init__.py')) as f: - init_text = f.read() - # license = re.search(r'__license__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1) - author = re.search(r'__author__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1) - author_email = re.search(r'__author_email__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1) - url = re.search(r'__url__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1) - -with open(path.join(root_dir, package_name, package_name, '__version__.py')) as f: - init_text = f.read() - version = re.search(r'__version__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1) - -setuptools.setup( - name=package_name, - version=version, - author=author, - author_email=author_email, - description="obniz sdk for python", - long_description=long_description, - long_description_content_type="text/markdown", - url=url, - packages=setuptools.find_packages(), - include_package_data=True, - install_requires=[ - 'pyee==6.0.0', - 'websockets>=12,<14', - 'attrdict3==2.0.2', - 'semver==2.8.1' - ], - python_requires='>=3.8', - classifiers=[ - "Programming Language :: Python :: 3", - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', - 'Programming Language :: Python :: 3.14', - "Operating System :: OS Independent", - ], -) diff --git a/tests/test_init.py b/tests/test_init.py index a329dbd..b5f9852 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -30,7 +30,7 @@ def test_connect(self): loop = asyncio.get_event_loop() future = loop.create_future() - async def on_connection(websocket, path): + async def on_connection(websocket): print("server: connected") future.set_result(None) @@ -53,7 +53,7 @@ def test_soft_redirect(self): loop = asyncio.get_event_loop() future = loop.create_future() - async def on_connection(websocket, path): + async def on_connection(websocket): try: print("server(" + str(port) + "): connected") future.set_result(websocket) @@ -79,7 +79,7 @@ async def on_connection(websocket, path): # expect(server.clients.size, 'before server not connected').to.equal(1) future2 = loop.create_future() - async def on_connection2(websocket, path): + async def on_connection2(websocket): try: print("server(" + str(port2) + "): connected") future2.set_result(None) diff --git a/tests/utils.py b/tests/utils.py index b3f1f6e..eab8448 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -4,6 +4,7 @@ import pytest import websockets +from websockets.protocol import State from obniz import Obniz from .obniz_json_validator import obniz_json_validator as validator @@ -13,9 +14,11 @@ def create_server(port, on_connection): - wss = websockets.serve(on_connection, "localhost", port) + async def _start(): + # websockets>=14 requires a running loop when the server is created + return await websockets.serve(on_connection, "localhost", port) - return asyncio.get_event_loop().run_until_complete(wss) + return asyncio.get_event_loop().run_until_complete(_start()) def create_obniz(port, obniz_id): @@ -25,7 +28,7 @@ def create_obniz(port, obniz_id): def setup_obniz(mocker): global server_data_count - stub = mocker.MagicMock(buffered_amount=0) + stub = mocker.MagicMock(buffered_amount=0, state=State.OPEN) # stub.on = mocker.stub() stub.send = AsyncMock() stub.close = AsyncMock() diff --git a/tox.ini b/tox.ini index 724f6de..7cd0364 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py38, py39, py310, py311, py312, py313, py314 +envlist = py39, py310, py311, py312, py313, py314 [testenv] deps =