diff --git a/.flake8 b/.flake8
new file mode 100644
index 000000000..5c1184f3e
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,9 @@
+[flake8]
+max-line-length = 88
+# E203: whitespace before ':' — black formats slices this way
+# E402: module level import not at top — spyne uses logging setup before imports throughout
+# W503: line break before binary operator — black preference
+extend-ignore = E203, E402, W503
+per-file-ignores =
+ # __init__.py files intentionally re-export symbols from submodules
+ */__init__.py: F401, F403, F811
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 000000000..e1e58aba6
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,28 @@
+name: Tests
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ unit-tests:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.10"
+
+ - name: Install pipenv
+ run: pip install pipenv
+
+ - name: Install dependencies
+ run: |
+ pipenv install --dev
+ pipenv run pip install .
+
+ - name: Run tests
+ run: pipenv run make test-isolated
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 000000000..9df87a5dd
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,18 @@
+variables:
+ KUBERNETES_MEMORY_REQUEST_DEFAULT: "2000Mi"
+ KUBERNETES_MEMORY_LIMIT_DEFAULT: "2000Mi"
+ CODE_QUALITY: false
+
+include:
+ - component: $CI_SERVER_FQDN/gitlab-ci/ci-toolbox/python-library@1.0.93
+
+
+unit-tests:
+ script:
+ # Install packages
+ - pip install pipenv
+ - pipenv install --dev
+ - pipenv run pip install .
+
+ # Run tests
+ - pipenv run make test-isolated
diff --git a/.pydev/base.conf b/.pydev/base.conf
new file mode 100644
index 000000000..ac116845b
--- /dev/null
+++ b/.pydev/base.conf
@@ -0,0 +1,16 @@
+VERSION_FILES=pyproject.toml
+
+ALIASES = '{
+ "install": {
+ "command": "sh \"pipenv install && pipenv run pip install .\"",
+ "description": "Build docker image with dependencies and run migrations"
+ },
+ "test": {
+ "command": "sh \"pipenv run pytest\"",
+ "description": "Run tests"
+ },
+ "reformat": {
+ "command": ["sh \"isort src\"", "sh \"autoflake -i --remove-all-unused-imports --recursive src\"", "sh \"black src\""],
+ "description": "Reformat code"
+ }
+}'
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..bbb1f75f8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,21 @@
+.PHONY: test test-isolated
+
+test:
+ pytest spyne/test/ -x -q
+
+test-isolated:
+ @failed_files=""; \
+ for f in $$(find spyne/test -name 'test_*.py' | sort); do \
+ printf '\n=== %s ===\n' "$$f"; \
+ if ! pytest $$f -x --tb=short -q 2>&1; then \
+ failed_files="$$failed_files $$f"; \
+ fi; \
+ done; \
+ echo ""; \
+ if [ -z "$$failed_files" ]; then \
+ echo "All files passed."; \
+ else \
+ echo "Failed files:"; \
+ for f in $$failed_files; do echo " $$f"; done; \
+ exit 1; \
+ fi
diff --git a/Pipfile b/Pipfile
new file mode 100644
index 000000000..a7f71601b
--- /dev/null
+++ b/Pipfile
@@ -0,0 +1,34 @@
+[[source]]
+url = "https://pypi.org/simple"
+verify_ssl = true
+name = "pypi"
+
+[packages]
+
+[dev-packages]
+pytest = ">=2.9"
+pytest-twisted = "*"
+pytest-cov = "*"
+coverage = "*"
+junitxml = "*"
+werkzeug = "*"
+sqlalchemy = "*"
+lxml = ">=3.6"
+pyyaml = "*"
+pyzmq = "*"
+twisted = "*"
+colorama = "*"
+msgpack = ">=1"
+webtest = "*"
+pytest-django = "*"
+django = "*"
+python-subunit = "*"
+pyramid = "*"
+tox = "*"
+pyparsing = ">=2.0.2"
+suds-community = "*"
+zeep = "*"
+pandas = "*"
+
+[requires]
+python_version = "3.10"
diff --git a/Pipfile.lock b/Pipfile.lock
new file mode 100644
index 000000000..cf3ca6b3f
--- /dev/null
+++ b/Pipfile.lock
@@ -0,0 +1,1617 @@
+{
+ "_meta": {
+ "hash": {
+ "sha256": "ea974184cf059f0c550554b145d30fee88b33715caef0daf3c7599ea79430b2d"
+ },
+ "pipfile-spec": 6,
+ "requires": {
+ "python_version": "3.10"
+ },
+ "sources": [
+ {
+ "name": "pypi",
+ "url": "https://pypi.org/simple",
+ "verify_ssl": true
+ }
+ ]
+ },
+ "default": {},
+ "develop": {
+ "asgiref": {
+ "hashes": [
+ "sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce",
+ "sha256:e8667a091e69529631969fd45dc268fa79b99c92c5fcdda727757e52146ec133"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==3.11.1"
+ },
+ "attrs": {
+ "hashes": [
+ "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309",
+ "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==26.1.0"
+ },
+ "automat": {
+ "hashes": [
+ "sha256:0017591a5477066e90d26b0e696ddc143baafd87b588cfac8100bc6be9634de0",
+ "sha256:04e9bce696a8d5671ee698005af6e5a9fa15354140a87f4870744604dcdd3ba1"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==25.4.16"
+ },
+ "beautifulsoup4": {
+ "hashes": [
+ "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb",
+ "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86"
+ ],
+ "markers": "python_full_version >= '3.7.0'",
+ "version": "==4.14.3"
+ },
+ "cachetools": {
+ "hashes": [
+ "sha256:4e94956cfdd3086f12042cdd29318f5ced3893014f7d0d059bf3ead3f85b7f8b",
+ "sha256:e5d524d36d65703a87243a26ff08ad84f73352adbeafb1cde81e207b456aaf24"
+ ],
+ "markers": "python_version >= '3.10'",
+ "version": "==7.0.6"
+ },
+ "certifi": {
+ "hashes": [
+ "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a",
+ "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==2026.4.22"
+ },
+ "charset-normalizer": {
+ "hashes": [
+ "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc",
+ "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c",
+ "sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67",
+ "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4",
+ "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0",
+ "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c",
+ "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5",
+ "sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444",
+ "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153",
+ "sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9",
+ "sha256:16d971e29578a5e97d7117866d15889a4a07befe0e87e703ed63cd90cb348c01",
+ "sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217",
+ "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b",
+ "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c",
+ "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a",
+ "sha256:1dc8b0ea451d6e69735094606991f32867807881400f808a106ee1d963c46a83",
+ "sha256:1efde3cae86c8c273f1eb3b287be7d8499420cf2fe7585c41d370d3e790054a5",
+ "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7",
+ "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb",
+ "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c",
+ "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1",
+ "sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42",
+ "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab",
+ "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df",
+ "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e",
+ "sha256:320ade88cfb846b8cd6b4ddf5ee9e80ee0c1f52401f2456b84ae1ae6a1a5f207",
+ "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18",
+ "sha256:36836d6ff945a00b88ba1e4572d721e60b5b8c98c155d465f56ad19d68f23734",
+ "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38",
+ "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110",
+ "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18",
+ "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44",
+ "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d",
+ "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48",
+ "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e",
+ "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5",
+ "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d",
+ "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53",
+ "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790",
+ "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c",
+ "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b",
+ "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116",
+ "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d",
+ "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10",
+ "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6",
+ "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2",
+ "sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776",
+ "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a",
+ "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265",
+ "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008",
+ "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943",
+ "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374",
+ "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246",
+ "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e",
+ "sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5",
+ "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616",
+ "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15",
+ "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41",
+ "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960",
+ "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752",
+ "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e",
+ "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72",
+ "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7",
+ "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8",
+ "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b",
+ "sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4",
+ "sha256:82b271f5137d07749f7bf32f70b17ab6eaabedd297e75dce75081a24f76eb545",
+ "sha256:84c018e49c3bf790f9c2771c45e9313a08c2c2a6342b162cd650258b57817706",
+ "sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366",
+ "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb",
+ "sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a",
+ "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e",
+ "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00",
+ "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f",
+ "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a",
+ "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1",
+ "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66",
+ "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356",
+ "sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319",
+ "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4",
+ "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad",
+ "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d",
+ "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5",
+ "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7",
+ "sha256:aef65cd602a6d0e0ff6f9930fcb1c8fec60dd2cfcb6facaf4bdb0e5873042db0",
+ "sha256:af21eb4409a119e365397b2adbaca4c9ccab56543a65d5dbd9f920d6ac29f686",
+ "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34",
+ "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49",
+ "sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c",
+ "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1",
+ "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e",
+ "sha256:bd9b23791fe793e4968dba0c447e12f78e425c59fc0e3b97f6450f4781f3ee60",
+ "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0",
+ "sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274",
+ "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d",
+ "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0",
+ "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae",
+ "sha256:c593052c465475e64bbfe5dbd81680f64a67fdc752c56d7a0ae205dc8aeefe0f",
+ "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d",
+ "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe",
+ "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3",
+ "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393",
+ "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1",
+ "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af",
+ "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44",
+ "sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00",
+ "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c",
+ "sha256:dca4bbc466a95ba9c0234ef56d7dd9509f63da22274589ebd4ed7f1f4d4c54e3",
+ "sha256:dd915403e231e6b1809fe9b6d9fc55cf8fb5e02765ac625d9cd623342a7905d7",
+ "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd",
+ "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e",
+ "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b",
+ "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8",
+ "sha256:e5f4d355f0a2b1a31bc3edec6795b46324349c9cb25eed068049e4f472fb4259",
+ "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859",
+ "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46",
+ "sha256:e80c8378d8f3d83cd3164da1ad2df9e37a666cdde7b1cb2298ed0b558064be30",
+ "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b",
+ "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46",
+ "sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24",
+ "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a",
+ "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24",
+ "sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc",
+ "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215",
+ "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063",
+ "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832",
+ "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6",
+ "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79",
+ "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==3.4.7"
+ },
+ "colorama": {
+ "hashes": [
+ "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44",
+ "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'",
+ "version": "==0.4.6"
+ },
+ "constantly": {
+ "hashes": [
+ "sha256:3fd9b4d1c3dc1ec9757f3c52aef7e53ad9323dbe39f51dfd4c43853b68dfa3f9",
+ "sha256:aa92b70a33e2ac0bb33cd745eb61776594dc48764b06c35e0efd050b7f1c7cbd"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==23.10.4"
+ },
+ "coverage": {
+ "extras": [
+ "toml"
+ ],
+ "hashes": [
+ "sha256:012d5319e66e9d5a218834642d6c35d265515a62f01157a45bcc036ecf947256",
+ "sha256:02ca0eed225b2ff301c474aeeeae27d26e2537942aa0f87491d3e147e784a82b",
+ "sha256:03ccc709a17a1de074fb1d11f217342fb0d2b1582ed544f554fc9fc3f07e95f5",
+ "sha256:0428cbef5783ad91fe240f673cc1f76b25e74bbfe1a13115e4aa30d3f538162d",
+ "sha256:04690832cbea4e4663d9149e05dba142546ca05cb1848816760e7f58285c970a",
+ "sha256:0590e44dd2745c696a778f7bab6aa95256de2cbc8b8cff4f7db8ff09813d6969",
+ "sha256:0672854dc733c342fa3e957e0605256d2bf5934feeac328da9e0b5449634a642",
+ "sha256:084b84a8c63e8d6fc7e3931b316a9bcafca1458d753c539db82d31ed20091a87",
+ "sha256:0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740",
+ "sha256:0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215",
+ "sha256:0cef0cdec915d11254a7f549c1170afecce708d30610c6abdded1f74e581666d",
+ "sha256:0e223ce4b4ed47f065bfb123687686512e37629be25cc63728557ae7db261422",
+ "sha256:0e3c426ffc4cd952f54ee9ffbdd10345709ecc78a3ecfd796a57236bfad0b9b8",
+ "sha256:0ecf12ecb326fe2c339d93fc131816f3a7367d223db37817208905c89bded911",
+ "sha256:10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b",
+ "sha256:145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587",
+ "sha256:1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8",
+ "sha256:1b88c69c8ef5d4b6fe7dea66d6636056a0f6a7527c440e890cf9259011f5e606",
+ "sha256:258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9",
+ "sha256:259b69bb83ad9894c4b25be2528139eecba9a82646ebdda2d9db1ba28424a6bf",
+ "sha256:2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633",
+ "sha256:2d3807015f138ffea1ed9afeeb8624fd781703f2858b62a8dd8da5a0994c57b6",
+ "sha256:301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43",
+ "sha256:32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2",
+ "sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61",
+ "sha256:356e76b46783a98c2a2fe81ec79df4883a1e62895ea952968fb253c114e7f930",
+ "sha256:35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc",
+ "sha256:380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247",
+ "sha256:3ad050321264c49c2fa67bb599100456fc51d004b82534f379d16445da40fb75",
+ "sha256:3e1bb5f6c78feeb1be3475789b14a0f0a5b47d505bfc7267126ccbd50289999e",
+ "sha256:3f4818d065964db3c1c66dc0fbdac5ac692ecbc875555e13374fdbe7eedb4376",
+ "sha256:460cf0114c5016fa841214ff5564aa4864f11948da9440bc97e21ad1f4ba1e01",
+ "sha256:48c39bc4a04d983a54a705a6389512883d4a3b9862991b3617d547940e9f52b1",
+ "sha256:4b59148601efcd2bac8c4dbf1f0ad6391693ccf7a74b8205781751637076aee3",
+ "sha256:4d2afbc5cc54d286bfb54541aa50b64cdb07a718227168c87b9e2fb8f25e1743",
+ "sha256:505d7083c8b0c87a8fa8c07370c285847c1f77739b22e299ad75a6af6c32c5c9",
+ "sha256:52f444e86475992506b32d4e5ca55c24fc88d73bcbda0e9745095b28ef4dc0cf",
+ "sha256:5b13955d31d1633cf9376908089b7cebe7d15ddad7aeaabcbe969a595a97e95e",
+ "sha256:5ec4af212df513e399cf11610cc27063f1586419e814755ab362e50a85ea69c1",
+ "sha256:60365289c3741e4db327e7baff2a4aaacf22f788e80fa4683393891b70a89fbd",
+ "sha256:631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b",
+ "sha256:6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab",
+ "sha256:66a80c616f80181f4d643b0f9e709d97bcea413ecd9631e1dedc7401c8e6695d",
+ "sha256:67e9bc5449801fad0e5dff329499fb090ba4c5800b86805c80617b4e29809b2a",
+ "sha256:68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0",
+ "sha256:6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510",
+ "sha256:6e3370441f4513c6252bf042b9c36d22491142385049243253c7e48398a15a9f",
+ "sha256:7034b5c56a58ae5e85f23949d52c14aca2cfc6848a31764995b7de88f13a1ea0",
+ "sha256:704de6328e3d612a8f6c07000a878ff38181ec3263d5a11da1db294fa6a9bdf8",
+ "sha256:7132bed4bd7b836200c591410ae7d97bf7ae8be6fc87d160b2bd881df929e7bf",
+ "sha256:7300c8a6d13335b29bb76d7651c66af6bd8658517c43499f110ddc6717bfc209",
+ "sha256:750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9",
+ "sha256:777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3",
+ "sha256:78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3",
+ "sha256:79060214983769c7ba3f0cee10b54c97609dca4d478fa1aa32b914480fd5738d",
+ "sha256:7c8d4bc913dd70b93488d6c496c77f3aff5ea99a07e36a18f865bca55adef8bd",
+ "sha256:7f2c47b36fe7709a6e83bfadf4eefb90bd25fbe4014d715224c4316f808e59a2",
+ "sha256:800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882",
+ "sha256:843ea8643cf967d1ac7e8ecd4bb00c99135adf4816c0c0593fdcc47b597fcf09",
+ "sha256:8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea",
+ "sha256:8dd02af98971bdb956363e4827d34425cb3df19ee550ef92855b0acb9c7ce51c",
+ "sha256:8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562",
+ "sha256:941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3",
+ "sha256:972a9cd27894afe4bc2b1480107054e062df08e671df7c2f18c205e805ccd806",
+ "sha256:9adb6688e3b53adffefd4a52d72cbd8b02602bfb8f74dcd862337182fd4d1a4e",
+ "sha256:9b74db26dfea4f4e50d48a4602207cd1e78be33182bc9cbf22da94f332f99878",
+ "sha256:9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e",
+ "sha256:9d44d7aa963820b1b971dbecd90bfe5fe8f81cff79787eb6cca15750bd2f79b9",
+ "sha256:9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45",
+ "sha256:9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29",
+ "sha256:a1a6d79a14e1ec1832cabc833898636ad5f3754a678ef8bb4908515208bf84f4",
+ "sha256:a698e363641b98843c517817db75373c83254781426e94ada3197cabbc2c919c",
+ "sha256:ad14385487393e386e2ea988b09d62dd42c397662ac2dabc3832d71253eee479",
+ "sha256:ad146744ca4fd09b50c482650e3c1b1f4dfa1d4792e0a04a369c7f23336f0400",
+ "sha256:b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c",
+ "sha256:bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a",
+ "sha256:bdba0a6b8812e8c7df002d908a9a2ea3c36e92611b5708633c50869e6d922fdf",
+ "sha256:be3d4bbad9d4b037791794ddeedd7d64a56f5933a2c1373e18e9e568b9141686",
+ "sha256:bf69236a9a81bdca3bff53796237aab096cdbf8d78a66ad61e992d9dac7eb2de",
+ "sha256:bff95879c33ec8da99fc9b6fe345ddb5be6414b41d6d1ad1c8f188d26f36e028",
+ "sha256:c555b48be1853fe3997c11c4bd521cdd9a9612352de01fa4508f16ec341e6fe0",
+ "sha256:c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179",
+ "sha256:c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16",
+ "sha256:ce1998c0483007608c8382f4ff50164bfc5bd07a2246dd272aa4043b75e61e85",
+ "sha256:cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a",
+ "sha256:cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0",
+ "sha256:d2c87e0c473a10bffe991502eac389220533024c8082ec1ce849f4218dded810",
+ "sha256:d7cfad2d6d81dd298ab6b89fe72c3b7b05ec7544bdda3b707ddaecff8d25c161",
+ "sha256:d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607",
+ "sha256:da305e9937617ee95c2e39d8ff9f040e0487cbf1ac174f777ed5eddd7a7c1f26",
+ "sha256:da86cdcf10d2519e10cabb8ac2de03da1bcb6e4853790b7fbd48523332e3a819",
+ "sha256:dc022073d063b25a402454e5712ef9e007113e3a676b96c5f29b2bda29352f40",
+ "sha256:e0723d2c96324561b9aa76fb982406e11d93cdb388a7a7da2b16e04719cf7ca5",
+ "sha256:e092b9499de38ae0fbfbc603a74660eb6ff3e869e507b50d85a13b6db9863e15",
+ "sha256:e0b216a19534b2427cc201a26c25da4a48633f29a487c61258643e89d28200c0",
+ "sha256:e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90",
+ "sha256:e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0",
+ "sha256:e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6",
+ "sha256:eb07647a5738b89baab047f14edd18ded523de60f3b30e75c2acc826f79c839a",
+ "sha256:eb7fdf1ef130660e7415e0253a01a7d5a88c9c4d158bcf75cbbd922fd65a5b58",
+ "sha256:ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b",
+ "sha256:ee2aa19e03161671ec964004fb74b2257805d9710bf14a5c704558b9d8dbaf17",
+ "sha256:f08fd75c50a760c7eb068ae823777268daaf16a80b918fa58eea888f8e3919f5",
+ "sha256:f4cd16206ad171cbc2470dbea9103cf9a7607d5fe8c242fdf1edf36174020664",
+ "sha256:f70c9ab2595c56f81a89620e22899eea8b212a4041bd728ac6f4a28bf5d3ddd0",
+ "sha256:fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.10'",
+ "version": "==7.13.5"
+ },
+ "decorator": {
+ "hashes": [
+ "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360",
+ "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==5.2.1"
+ },
+ "distlib": {
+ "hashes": [
+ "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16",
+ "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"
+ ],
+ "version": "==0.4.0"
+ },
+ "django": {
+ "hashes": [
+ "sha256:5788fce61da23788a8ce6f02583765ab060d396720924789f97fa42119d37f7a",
+ "sha256:a31589db5188d074c63f0945c3888fad104627dfcc236fb2b97f71f89da33bc4"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.10'",
+ "version": "==5.2.13"
+ },
+ "exceptiongroup": {
+ "hashes": [
+ "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219",
+ "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==1.3.1"
+ },
+ "filelock": {
+ "hashes": [
+ "sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90",
+ "sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258"
+ ],
+ "markers": "python_version >= '3.10'",
+ "version": "==3.29.0"
+ },
+ "greenlet": {
+ "hashes": [
+ "sha256:04403ac74fe295a361f650818de93be11b5038a78f49ccfb64d3b1be8fbf1267",
+ "sha256:05fa0803561028f4b2e3b490ee41216a842eaee11aed004cc343a996d9523aa2",
+ "sha256:06c2d3b89e0c62ba50bd7adf491b14f39da9e7e701647cb7b9ff4c99bee04b19",
+ "sha256:070b8bac2ff3b4d9e0ff36a0d19e42103331d9737e8504747cd1e659f76297bd",
+ "sha256:076e21040b3a917d3ce4ad68fb5c3c6b32f1405616c4a57aa83120979649bd3d",
+ "sha256:0e1254cf0cbaa17b04320c3a78575f29f3c161ef38f59c977108f19ffddaf077",
+ "sha256:1054c5a3c78e2ab599d452f23f7adafef55062a783a8e241d24f3b633ba6ff82",
+ "sha256:10a07aca6babdd18c16a3f4f8880acfffc2b88dfe431ad6aa5f5740759d7d75e",
+ "sha256:16dec271460a9a2b154e3b1c2fa1050ce6280878430320e85e08c166772e3f97",
+ "sha256:1a4a48f24681300c640f143ba7c404270e1ebbbcf34331d7104a4ff40f8ea705",
+ "sha256:1a54a921561dd9518d31d2d3db4d7f80e589083063ab4d3e2e950756ef809e1a",
+ "sha256:1f85f204c4d54134ae850d401fa435c89cd667d5ce9dc567571776b45941af72",
+ "sha256:207ba5b97ea8b0b60eb43ffcacf26969dd83726095161d676aac03ff913ee50d",
+ "sha256:227a46251ecba4ff46ae742bc5ce95c91d5aceb4b02f885487aff269c127a729",
+ "sha256:234582c20af9742583c3b2ddfbdbb58a756cfff803763ffaae1ac7990a9fac31",
+ "sha256:2d4f0635dc4aa638cda4b2f5a07ae9a2cff9280327b581a3fcb6f317b4fbc38a",
+ "sha256:43748988b097f9c6f09364f260741aa73c80747f63389824435c7a50bfdfd5c1",
+ "sha256:439fc2f12b9b512d9dfa681c5afe5f6b3232c708d13e6f02c845e0d9f4c2d8c6",
+ "sha256:4df3b0b2289ec686d3c821a5fee44259c05cfe824dd5e6e12c8e5f5df23085cf",
+ "sha256:523677e69cd4711b5a014e37bc1fb3a29947c3e3a5bb6a527e1cc50312e5a398",
+ "sha256:5434271357be07f3ad0936c312645853b7e689e679e29310e2de09a9ea6c3adf",
+ "sha256:5566e4e2cd7a880e8c27618e3eab20f3494452d12fd5129edef7b2f7aa9a36d1",
+ "sha256:5b99e87be7eba788dd5b75ba1cde5639edffdec5f91fe0d734a249535ec3408c",
+ "sha256:5cb614ace7c27571270354e9c9f696554d073f8aa9319079dcba466bbdead711",
+ "sha256:636d2f95c309e35f650e421c23297d5011716be15d966e6328b367c9fc513a82",
+ "sha256:6f0def07ec9a71d72315cf26c061aceee53b306c36ed38c35caba952ea1b319d",
+ "sha256:7f50c804733b43eded05ae694691c9aa68bca7d0a867d67d4a3f514742a2d53f",
+ "sha256:805bebb4945094acbab757d34d6e1098be6de8966009ab9ca54f06ff492def58",
+ "sha256:8424683caf46eb0eb6f626cb95e008e8cc30d0cb675bdfa48200925c79b38a08",
+ "sha256:849f8bc17acd6295fcb5de8e46d55cc0e52381c56eaf50a2afd258e97bc65940",
+ "sha256:89995ce5ddcd2896d89615116dd39b9703bfa0c07b583b85b89bf1b5d6eddf81",
+ "sha256:8a569c2fb840c53c13a2b8967c63621fafbd1a0e015b9c82f408c33d626a2fda",
+ "sha256:8bff29d586ea415688f4cec96a591fcc3bf762d046a796cdadc1fdb6e7f2d5bf",
+ "sha256:8c5696c42e6bb5cfb7c6ff4453789081c66b9b91f061e5e9367fa15792644e76",
+ "sha256:90036ce224ed6fe75508c1907a77e4540176dcf0744473627785dd519c6f9996",
+ "sha256:9390ad88b652b1903814eaabd629ca184db15e0eeb6fe8a390bbf8b9106ae15a",
+ "sha256:956215d5e355fffa7c021d168728321fd4d31fd730ac609b1653b450f6a4bc71",
+ "sha256:98eedd1803353daf1cd9ef23eef23eda5a4d22f99b1f998d273a8b78b70dd47f",
+ "sha256:9b2d9a138ffa0e306d0e2b72976d2fb10b97e690d40ab36a472acaab0838e2de",
+ "sha256:a0a53fb071531d003b075c444014ff8f8b1a9898d36bb88abd9ac7b3524648a2",
+ "sha256:a19093fbad824ed7c0f355b5ff4214bffda5f1a7f35f29b31fcaa240cc0135ab",
+ "sha256:a1c4f6b453006efb8310affb2d132832e9bbb4fc01ce6df6b70d810d38f1f6dc",
+ "sha256:a58bec0751f43068cd40cff31bb3ca02ad6000b3a51ca81367af4eb5abc480c8",
+ "sha256:a70ed1cb0295bee1df57b63bf7f46b4e56a5c93709eea769c1fec1bb23a95875",
+ "sha256:ac6a5f618be581e1e0713aecec8e54093c235e5fa17d6d8eb7ffc487e2300508",
+ "sha256:b45e45fe47a19051a396abb22e19e7836a59ee6c5a90f3be427343c37908d65b",
+ "sha256:b7857e2202aae67bc5725e0c1f6403c20a8ff46094ece015e7d474f5f7020b55",
+ "sha256:c4cd56a9eb7a6444edbc19062f7b6fbc8f287c663b946e3171d899693b1c19fa",
+ "sha256:c660bce1940a1acae5f51f0a064f1bc785d07ea16efcb4bc708090afc4d69e83",
+ "sha256:d18eae9a7fb0f499efcd146b8c9750a2e1f6e0e93b5a382b3481875354a430e6",
+ "sha256:d336d46878e486de7d9458653c722875547ac8d36a1cff9ffaf4a74a3c1f62eb",
+ "sha256:d70012e51df2dbbccfaf63a40aaf9b40c8bed37c3e3a38751c926301ce538ece",
+ "sha256:e60d38719cb80b3ab5e85f9f1aed4960acfde09868af6762ccb27b260d68f4ed",
+ "sha256:e82689eea4a237e530bb5cb41b180ef81fa2160e1f89422a67be7d90da67f615",
+ "sha256:ee407d4d1ca9dc632265aee1c8732c4a2d60adff848057cdebfe5fe94eb2c8a2",
+ "sha256:f38b81880ba28f232f1f675893a39cf7b6db25b31cc0a09bb50787ecf957e85e",
+ "sha256:f50a96b64dafd6169e595a5c56c9146ef80333e67d4476a65a9c55f400fc22ff",
+ "sha256:f8296d4e2b92af34ebde81085a01690f26a51eb9ac09a0fcadb331eb36dbc802",
+ "sha256:f82cb6cddc27dd81c96b1506f4aa7def15070c3b2a67d4e46fd19016aacce6cf"
+ ],
+ "markers": "python_version >= '3.10'",
+ "version": "==3.4.0"
+ },
+ "hupper": {
+ "hashes": [
+ "sha256:06bf54170ff4ecf4c84ad5f188dee3901173ab449c2608ad05b9bfd6b13e32eb",
+ "sha256:e872b959f09d90be5fb615bd2e62de89a0b57efc037bdf9637fb09cdf8552b19"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==1.12.1"
+ },
+ "hyperlink": {
+ "hashes": [
+ "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b",
+ "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"
+ ],
+ "version": "==21.0.0"
+ },
+ "idna": {
+ "hashes": [
+ "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242",
+ "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==3.13"
+ },
+ "incremental": {
+ "hashes": [
+ "sha256:87d3480dbb083c1d736222511a8cf380012a8176c2456d01ef483242abbbcf8c",
+ "sha256:a34450716b1c4341fe6676a0598e88a39e04189f4dce5dc96f656e040baa10b3"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==24.11.0"
+ },
+ "iniconfig": {
+ "hashes": [
+ "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730",
+ "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"
+ ],
+ "markers": "python_version >= '3.10'",
+ "version": "==2.3.0"
+ },
+ "iso8601": {
+ "hashes": [
+ "sha256:6b1d3829ee8921c4301998c909f7829fa9ed3cbdac0d3b16af2d743aed1ba8df",
+ "sha256:aac4145c4dcb66ad8b648a02830f5e2ff6c24af20f4f482689be402db2429242"
+ ],
+ "markers": "python_version >= '3.7' and python_version < '4.0'",
+ "version": "==2.1.0"
+ },
+ "isodate": {
+ "hashes": [
+ "sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15",
+ "sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==0.7.2"
+ },
+ "junitxml": {
+ "hashes": [
+ "sha256:a5901127067ab7f3d11df30727368c129c69b3f5595c697daf4f5ed80b1baaa3"
+ ],
+ "index": "pypi",
+ "version": "==0.7"
+ },
+ "lxml": {
+ "hashes": [
+ "sha256:00750d63ef0031a05331b9223463b1c7c02b9004cef2346a5b2877f0f9494dd2",
+ "sha256:022981127642fe19866d2907d76241bb07ed21749601f727d5d5dd1ce5d1b773",
+ "sha256:045e387d1f4f42a418380930fa3f45c73c9b392faf67e495e58902e68e8f44a7",
+ "sha256:05b9b8787e35bec69e68daf4952b2e6dfcfb0db7ecf1a06f8cdfbbac4eb71aad",
+ "sha256:07f98f5496f96bf724b1e3c933c107f0cbf2745db18c03d2e13a291c3afd2635",
+ "sha256:08950a23f296b3f83521577274e3d3b0f3d739bf2e68d01a752e4288bc50d286",
+ "sha256:0d082495c5fcf426e425a6e28daaba1fcb6d8f854a4ff01effb1f1f381203eb9",
+ "sha256:0f0f08beb0182e3e9a86fae124b3c47a7b41b7b69b225e1377db983802404e54",
+ "sha256:1081dd10bc6fa437db2500e13993abf7cc30716d0a2f40e65abb935f02ec559c",
+ "sha256:11a873c77a181b4fef9c2e357d08ed399542c2af1390101da66720a19c7c9618",
+ "sha256:183bfb45a493081943be7ea2b5adfc2b611e1cf377cefa8b8a8be404f45ef9a7",
+ "sha256:19f4164243fc206d12ed3d866e80e74f5bc3627966520da1a5f97e42c32a3f39",
+ "sha256:1ae225f66e5938f4fa29d37e009a3bb3b13032ac57eb4eb42afa44f6e4054e69",
+ "sha256:1bc4cc83fb7f66ffb16f74d6dd0162e144333fc36ebcce32246f80c8735b2551",
+ "sha256:1dd6a1c3ad4cb674f44525d9957f3e9c209bb6dd9213245195167a281fcc2bdc",
+ "sha256:20cf4d0651987c906a2f5cba4e3a8d6ba4bfdf973cfe2a96c0d6053888ea2ecd",
+ "sha256:2173a7bffe97667bbf0767f8a99e587740a8c56fdf3befac4b09cb29a80276fd",
+ "sha256:21c3302068f50d1e8728c67c87ba92aa87043abee517aa2576cca1855326b405",
+ "sha256:23a5dc68e08ed13331d61815c08f260f46b4a60fdd1640bbeb82cf89a9d90289",
+ "sha256:23cad0cc86046d4222f7f418910e46b89971c5a45d3c8abfad0f64b7b05e4a9b",
+ "sha256:2593a0a6621545b9095b71ad74ed4226eba438a7d9fc3712a99bdb15508cf93a",
+ "sha256:264c605ab9c0e4aa1a679636f4582c4d3313700009fac3ec9c3412ed0d8f3e1d",
+ "sha256:26c5272c6a4bf4cf32d3f5a7890c942b0e04438691157d341616d02cca74d4bd",
+ "sha256:26dd9f57ee3bd41e7d35b4c98a2ffd89ed11591649f421f0ec19f67d50ec67ac",
+ "sha256:28902146ffbe5222df411c5d19e5352490122e14447e98cd118907ee3fd6ee62",
+ "sha256:29f5c00cb7d752bce2c70ebd2d31b0a42f9499ffdd3ecb2f31a5b73ee43031ad",
+ "sha256:30e7b2ed63b6c8e97cca8af048589a788ab5c9c905f36d9cf1c2bb549f450d2f",
+ "sha256:32662519149fd7a9db354175aa5e417d83485a8039b8aaa62f873ceee7ea4cad",
+ "sha256:363e47283bde87051b821826e71dde47f107e08614e1aa312ba0c5711e77738c",
+ "sha256:3648f20d25102a22b6061c688beb3a805099ea4beb0a01ce62975d926944d292",
+ "sha256:37448bf9c7d7adfc5254763901e2bbd6bb876228dfc1fc7f66e58c06368a7544",
+ "sha256:37fabd1452852636cf38ecdcc9dd5ca4bba7a35d6c53fa09725deeb894a87491",
+ "sha256:398443df51c538bd578529aa7e5f7afc6c292644174b47961f3bf87fe5741120",
+ "sha256:3ae5d8d5427f3cc317e7950f2da7ad276df0cfa37b8de2f5658959e618ea8512",
+ "sha256:3f00972f84450204cd5d93a5395965e348956aaceaadec693a22ec743f8ae3eb",
+ "sha256:40d9189f80075f2e1f88db21ef815a2b17b28adf8e50aaf5c789bfe737027f32",
+ "sha256:419c58fc92cc3a2c3fa5f78c63dbf5da70c1fa9c1b25f25727ecee89a96c7de2",
+ "sha256:41dcc4c7b10484257cbd6c37b83ddb26df2b0e5aff5ac00d095689015af868ec",
+ "sha256:43e4d297f11080ec9d64a4b1ad7ac02b4484c9f0e2179d9c4ef78e886e747b88",
+ "sha256:45e9dfbd1b661eb64ba0d4dbe762bd210c42d86dd1e5bd2bdf89d634231beb43",
+ "sha256:4642e04449a1e164b5ff71ffd901ddb772dfabf5c9adf1b7be5dffe1212bc037",
+ "sha256:468479e52ecf3ec23799c863336d02c05fc2f7ffd1a1424eeeb9a28d4eb69d13",
+ "sha256:47024feaae386a92a146af0d2aeed65229bf6fff738e6a11dda6b0015fb8fd03",
+ "sha256:481d6e2104285d9add34f41b42b247b76b61c5b5c26c303c2e9707bbf8bd9a64",
+ "sha256:4937460dc5df0cdd2f06a86c285c28afda06aefa3af949f9477d3e8df430c485",
+ "sha256:4a1503c56e4e2b38dc76f2f2da7bae69670c0f1933e27cfa34b2fa5876410b16",
+ "sha256:4b89b098105b8599dc57adac95d1813409ac476d3c948a498775d3d0c6124bfb",
+ "sha256:4bd1bdb8a9e0e2dd229de19b5f8aebac80e916921b4b2c6ef8a52bc131d0c1f9",
+ "sha256:4e2c54d6b47361d0f1d3bc8d4e082ad87201e56ccdcca4d3b9ee3644ff595ec8",
+ "sha256:52b0ac6903cf74ebf997eb8c682d2fbac7d1ab7e4c552413eec55868a9b73f39",
+ "sha256:546b66c0dd1bb8d9fa89d7123e5fa19a8aff3a1f2141eb22df96112afb17b842",
+ "sha256:56971379bc5ee8037c5a0f09fa88f66cdb7d37c3e38af3e45cf539f41131ac1f",
+ "sha256:5715e0e28736a070f3f34a7ccc09e2fdcba0e3060abbcf61a1a5718ff6d6b105",
+ "sha256:5cfa1a34df366d9dc0d5eaf420f4cf2bb1e1bebe1066d1c2fc28c179f8a4004c",
+ "sha256:5d27bbe326c6b539c64b42638b18bc6003a8d88f76213a97ac9ed4f885efeab7",
+ "sha256:6262b87f9e5c1e5fe501d6c153247289af42eb44ad7660b9b3de17baaf92d6f6",
+ "sha256:63aeafc26aac0be8aff14af7871249e87ea1319be92090bfd632ec68e03b16a5",
+ "sha256:690022c7fae793b0489aa68a658822cea83e0d5933781811cabbf5ea3bcfe73d",
+ "sha256:6fd8b1df8254ff4fd93fd31da1fc15770bde23ac045be9bb1f87425702f61cc9",
+ "sha256:73becf6d8c81d4c76b1014dbd3584cb26d904492dcf73ca85dc8bff08dcd6d2d",
+ "sha256:73d658216fc173cf2c939e90e07b941c5e12736b0bf6a99e7af95459cfe8eabb",
+ "sha256:75c4c7c619a744f972f4451bf5adf6d0fb00992a1ffc9fd78e13b0bc817cc99f",
+ "sha256:76b958b4ea3104483c20f74866d55aa056546e15ebe83dd7aecd63698f43b755",
+ "sha256:77b9f99b17cbf14026d1e618035077060fc7195dd940d025149f3e2e830fbfcb",
+ "sha256:7ba11752e346bd804ea312ec2eea2532dfa8b8d3261d81a32ef9e6ab16256280",
+ "sha256:7da13bb6fbadfafb474e0226a30570a3445cfd47c86296f2446dafbd77079ace",
+ "sha256:7e39ab3a28af7784e206d8606ec0e4bcad0190f63a492bca95e94e5a4aef7f6e",
+ "sha256:7f4a77d6f7edf9230cee3e1f7f6764722a41604ee5681844f18db9a81ea0ec33",
+ "sha256:80410c3a7e3c617af04de17caa9f9f20adaa817093293d69eae7d7d0522836f5",
+ "sha256:81ff55c70b67d19d52b6fd118a114c0a4c97d799cd3089ff9bd9e2ff4b414ee2",
+ "sha256:857efde87d365706590847b916baff69c0bc9252dc5af030e378c9800c0b10e3",
+ "sha256:89e8d73d09ac696a5ba42ec69787913d53284f12092f651506779314f10ba585",
+ "sha256:8c11b984b5ce6add4dccc7144c7be5d364d298f15b0c6a57da1991baedc750ce",
+ "sha256:8c8984e1d8c4b3949e419158fda14d921ff703a9ed8a47236c6eb7a2b6cb4946",
+ "sha256:8e369cbd690e788c8d15e56222d91a09c6a417f49cbc543040cba0fe2e25a79e",
+ "sha256:9147d8e386ec3b82c3b15d88927f734f565b0aaadef7def562b853adca45784a",
+ "sha256:920354904d1cb86577d4b3cfe2830c2dbe81d6f4449e57ada428f1609b5985f7",
+ "sha256:942454ff253da14218f972b23dc72fa4edf6c943f37edd19cd697618b626fac5",
+ "sha256:972a6451204798675407beaad97b868d0c733d9a74dafefc63120b81b8c2de28",
+ "sha256:976a6b39b1b13e8c354ad8d3f261f3a4ac6609518af91bdb5094760a08f132c4",
+ "sha256:97faa0860e13b05b15a51fb4986421ef7a30f0b3334061c416e0981e9450ca4c",
+ "sha256:9c03e048b6ce8e77b09c734e931584894ecd58d08296804ca2d0b184c933ce50",
+ "sha256:9e7b0a4ca6dcc007a4cef00a761bba2dea959de4bd2df98f926b33c92ca5dfb9",
+ "sha256:9eb667bf50856c4a58145f8ca2d5e5be160191e79eb9e30855a476191b3c3495",
+ "sha256:9f93d5b8b07f73e8c77e3c6556a3db269918390c804b5e5fcdd4858232cc8f16",
+ "sha256:a0092f2b107b69601adf562a57c956fbb596e05e3e6651cabd3054113b007e45",
+ "sha256:a02ca8fe48815bddcfca3248efe54451abb9dbf2f7d1c5744c8aa4142d476919",
+ "sha256:a1d9b99e5b2597e4f5aed2484fef835256fa1b68a19e4265c97628ef4bf8bcf4",
+ "sha256:a2853c8b2170cc6cd54a6b4d50d2c1a8a7aeca201f23804b4898525c7a152cfc",
+ "sha256:a31286dbb5e74c8e9a5344465b77ab4c5bd511a253b355b5ca2fae7e579fafec",
+ "sha256:a86f06f059e22a0d574990ee2df24ede03f7f3c68c1336293eee9536c4c776cd",
+ "sha256:ab863fd37458fed6456525f297d21239d987800c46e67da5ef04fc6b3dd93ac8",
+ "sha256:ac4db068889f8772a4a698c5980ec302771bb545e10c4b095d4c8be26749616f",
+ "sha256:b6c2f225662bc5ad416bdd06f72ca301b31b39ce4261f0e0097017fc2891b940",
+ "sha256:bb40648d96157f9081886defe13eac99253e663be969ff938a9289eff6e47b72",
+ "sha256:bba078de0031c219e5dd06cf3e6bf8fb8e6e64a77819b358f53bb132e3e03366",
+ "sha256:bc783ee3147e60a25aa0445ea82b3e8aabb83b240f2b95d32cb75587ff781814",
+ "sha256:be10838781cb3be19251e276910cd508fe127e27c3242e50521521a0f3781690",
+ "sha256:bfd57d8008c4965709a919c3e9a98f76c2c7cb319086b3d26858250620023b13",
+ "sha256:c08da09dc003c9e8c70e06b53a11db6fb3b250c21c4236b03c7d7b443c318e7a",
+ "sha256:c3592631e652afa34999a088f98ba7dfc7d6aff0d535c410bea77a71743f3819",
+ "sha256:c4a699432846df86cc3de502ee85f445ebad748a1c6021d445f3e514d2cd4b1c",
+ "sha256:c4e425db0c5445ef0ad56b0eec54f89b88b2d884656e536a90b2f52aecb4ca86",
+ "sha256:c53fa3a5a52122d590e847a57ccf955557b9634a7f99ff5a35131321b0a85317",
+ "sha256:c6854e9cf99c84beb004eecd7d3a3868ef1109bf2b1df92d7bc11e96a36c2180",
+ "sha256:c748ebcb6877de89f48ab90ca96642ac458fff5dec291a2b9337cd4d0934e383",
+ "sha256:c871299c595ee004d186f61840f0bfc4941aa3f17c8ba4a565ead7e4f4f820ee",
+ "sha256:cbd7b79cdcb4986ad78a2662625882747f09db5e4cd7b2ae178a88c9c51b3dfe",
+ "sha256:cc16682cc987a3da00aa56a3aa3075b08edb10d9b1e476938cfdbee8f3b67181",
+ "sha256:cec05be8c876f92a5aa07b01d60bbb4d11cfbdd654cad0561c0d7b5c043a61b9",
+ "sha256:d036ee7b99d5148072ac7c9b847193decdfeac633db350363f7bce4fff108f0e",
+ "sha256:d0d799ff958655781296ec870d5e2448e75150da2b3d07f13ff5b0c2c35beefd",
+ "sha256:d1392c569c032f78a11a25d1de1c43fff13294c793b39e19d84fade3045cbbc3",
+ "sha256:d2f17a16cd8751e8eb233a7e41aecdf8e511712e00088bf9be455f604cd0d28d",
+ "sha256:d3829a6e6fd550a219564912d4002c537f65da4c6ae4e093cc34462f4fa027ad",
+ "sha256:d43aa26dcda363f21e79afa0668f5029ed7394b3bb8c92a6927a3d34e8b610ea",
+ "sha256:d6d8efe71429635f0559579092bb5e60560d7b9115ee38c4adbea35632e7fa24",
+ "sha256:dabecc48db5f42ba348d1f5d5afdc54c6c4cc758e676926c7cd327045749517d",
+ "sha256:db88156fcf544cdbf0d95588051515cfdfd4c876fc66444eb98bceb5d6db76de",
+ "sha256:de550d129f18d8ab819651ffe4f38b1b713c7e116707de3c0c6400d0ef34fbc1",
+ "sha256:e0af85773850417d994d019741239b901b22c6680206f46a34766926e466141d",
+ "sha256:e3c4f84b24a1fcba435157d111c4b755099c6ff00a3daee1ad281817de75ed11",
+ "sha256:e3dd5fe19c9e0ac818a9c7f132a5e43c1339ec1cbbfecb1a938bd3a47875b7c9",
+ "sha256:e69aa6805905807186eb00e66c6d97a935c928275182eb02ee40ba00da9623b2",
+ "sha256:e80807d72f96b96ad5588cb85c75616e4f2795a7737d4630784c51497beb7776",
+ "sha256:ebe33f4ec1b2de38ceb225a1749a2965855bffeef435ba93cd2d5d540783bf2f",
+ "sha256:f0cea5b1d3e6e77d71bd2b9972eb2446221a69dc52bb0b9c3c6f6e5700592d93",
+ "sha256:f15401d8d3dbf239e23c818afc10c7207f7b95f9a307e092122b6f86dd43209a",
+ "sha256:f504d861d9f2a8f94020130adac88d66de93841707a23a86244263d1e54682f5",
+ "sha256:fc46da94826188ed45cb53bd8e3fc076ae22675aea2087843d4735627f867c6d",
+ "sha256:fc7140d7a7386e6b545d41b7358f4d02b656d4053f5fa6859f92f4b9c2572c4d",
+ "sha256:fcf3da95e93349e0647d48d4b36a12783105bcc74cb0c416952f9988410846a3",
+ "sha256:fe022f20bc4569ec66b63b3fb275a3d628d9d32da6326b2982584104db6d3086",
+ "sha256:ffb34ea45a82dd637c2c97ae1bbb920850c1e59bcae79ce1c15af531d83e7215"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.8'",
+ "version": "==6.1.0"
+ },
+ "markupsafe": {
+ "hashes": [
+ "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f",
+ "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a",
+ "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf",
+ "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19",
+ "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf",
+ "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c",
+ "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175",
+ "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219",
+ "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb",
+ "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6",
+ "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab",
+ "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26",
+ "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1",
+ "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce",
+ "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218",
+ "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634",
+ "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695",
+ "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad",
+ "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73",
+ "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c",
+ "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe",
+ "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa",
+ "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559",
+ "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa",
+ "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37",
+ "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758",
+ "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f",
+ "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8",
+ "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d",
+ "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c",
+ "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97",
+ "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a",
+ "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19",
+ "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9",
+ "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9",
+ "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc",
+ "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2",
+ "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4",
+ "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354",
+ "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50",
+ "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698",
+ "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9",
+ "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b",
+ "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc",
+ "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115",
+ "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e",
+ "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485",
+ "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f",
+ "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12",
+ "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025",
+ "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009",
+ "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d",
+ "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b",
+ "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a",
+ "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5",
+ "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f",
+ "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d",
+ "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1",
+ "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287",
+ "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6",
+ "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f",
+ "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581",
+ "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed",
+ "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b",
+ "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c",
+ "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026",
+ "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8",
+ "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676",
+ "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6",
+ "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e",
+ "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d",
+ "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d",
+ "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01",
+ "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7",
+ "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419",
+ "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795",
+ "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1",
+ "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5",
+ "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d",
+ "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42",
+ "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe",
+ "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda",
+ "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e",
+ "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737",
+ "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523",
+ "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591",
+ "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc",
+ "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a",
+ "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==3.0.3"
+ },
+ "msgpack": {
+ "hashes": [
+ "sha256:0051fffef5a37ca2cd16978ae4f0aef92f164df86823871b5162812bebecd8e2",
+ "sha256:04fb995247a6e83830b62f0b07bf36540c213f6eac8e851166d8d86d83cbd014",
+ "sha256:180759d89a057eab503cf62eeec0aa61c4ea1200dee709f3a8e9397dbb3b6931",
+ "sha256:1d1418482b1ee984625d88aa9585db570180c286d942da463533b238b98b812b",
+ "sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b",
+ "sha256:1fdf7d83102bf09e7ce3357de96c59b627395352a4024f6e2458501f158bf999",
+ "sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029",
+ "sha256:283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0",
+ "sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9",
+ "sha256:2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c",
+ "sha256:350ad5353a467d9e3b126d8d1b90fe05ad081e2e1cef5753f8c345217c37e7b8",
+ "sha256:354e81bcdebaab427c3df4281187edc765d5d76bfb3a7c125af9da7a27e8458f",
+ "sha256:365c0bbe981a27d8932da71af63ef86acc59ed5c01ad929e09a0b88c6294e28a",
+ "sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42",
+ "sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e",
+ "sha256:41d1a5d875680166d3ac5c38573896453bbbea7092936d2e107214daf43b1d4f",
+ "sha256:42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7",
+ "sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb",
+ "sha256:454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef",
+ "sha256:4efd7b5979ccb539c221a4c4e16aac1a533efc97f3b759bb5a5ac9f6d10383bf",
+ "sha256:5559d03930d3aa0f3aacb4c42c776af1a2ace2611871c84a75afe436695e6245",
+ "sha256:5928604de9b032bc17f5099496417f113c45bc6bc21b5c6920caf34b3c428794",
+ "sha256:59415c6076b1e30e563eb732e23b994a61c159cec44deaf584e5cc1dd662f2af",
+ "sha256:5a46bf7e831d09470ad92dff02b8b1ac92175ca36b087f904a0519857c6be3ff",
+ "sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e",
+ "sha256:61c8aa3bd513d87c72ed0b37b53dd5c5a0f58f2ff9f26e1555d3bd7948fb7296",
+ "sha256:67016ae8c8965124fdede9d3769528ad8284f14d635337ffa6a713a580f6c030",
+ "sha256:6bde749afe671dc44893f8d08e83bf475a1a14570d67c4bb5cec5573463c8833",
+ "sha256:6c15b7d74c939ebe620dd8e559384be806204d73b4f9356320632d783d1f7939",
+ "sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa",
+ "sha256:70c5a7a9fea7f036b716191c29047374c10721c389c21e9ffafad04df8c52c90",
+ "sha256:7bc8813f88417599564fafa59fd6f95be417179f76b40325b500b3c98409757c",
+ "sha256:80a0ff7d4abf5fecb995fcf235d4064b9a9a8a40a3ab80999e6ac1e30b702717",
+ "sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406",
+ "sha256:897c478140877e5307760b0ea66e0932738879e7aa68144d9b78ea4c8302a84a",
+ "sha256:8b696e83c9f1532b4af884045ba7f3aa741a63b2bc22617293a2c6a7c645f251",
+ "sha256:8e22ab046fa7ede9e36eeb4cfad44d46450f37bb05d5ec482b02868f451c95e2",
+ "sha256:94fd7dc7d8cb0a54432f296f2246bc39474e017204ca6f4ff345941d4ed285a7",
+ "sha256:99e2cb7b9031568a2a5c73aa077180f93dd2e95b4f8d3b8e14a73ae94a9e667e",
+ "sha256:9ade919fac6a3e7260b7f64cea89df6bec59104987cbea34d34a2fa15d74310b",
+ "sha256:9fba231af7a933400238cb357ecccf8ab5d51535ea95d94fc35b7806218ff844",
+ "sha256:a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9",
+ "sha256:a605409040f2da88676e9c9e5853b3449ba8011973616189ea5ee55ddbc5bc87",
+ "sha256:a668204fa43e6d02f89dbe79a30b0d67238d9ec4c5bd8a940fc3a004a47b721b",
+ "sha256:a7787d353595c7c7e145e2331abf8b7ff1e6673a6b974ded96e6d4ec09f00c8c",
+ "sha256:a8f6e7d30253714751aa0b0c84ae28948e852ee7fb0524082e6716769124bc23",
+ "sha256:ad09b984828d6b7bb52d1d1d0c9be68ad781fa004ca39216c8a1e63c0f34ba3c",
+ "sha256:bafca952dc13907bdfdedfc6a5f579bf4f292bdd506fadb38389afa3ac5b208e",
+ "sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620",
+ "sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69",
+ "sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f",
+ "sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68",
+ "sha256:d62ce1f483f355f61adb5433ebfd8868c5f078d1a52d042b0a998682b4fa8c27",
+ "sha256:d99ef64f349d5ec3293688e91486c5fdb925ed03807f64d98d205d2713c60b46",
+ "sha256:db6192777d943bdaaafb6ba66d44bf65aa0e9c5616fa1d2da9bb08828c6b39aa",
+ "sha256:e23ce8d5f7aa6ea6d2a2b326b4ba46c985dbb204523759984430db7114f8aa00",
+ "sha256:e64c8d2f5e5d5fda7b842f55dec6133260ea8f53c4257d64494c534f306bf7a9",
+ "sha256:e69b39f8c0aa5ec24b57737ebee40be647035158f14ed4b40e6f150077e21a84",
+ "sha256:ea5405c46e690122a76531ab97a079e184c0daf491e588592d6a23d3e32af99e",
+ "sha256:f2cb069d8b981abc72b41aea1c580ce92d57c673ec61af4c500153a626cb9e20",
+ "sha256:fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e",
+ "sha256:fffee09044073e69f2bad787071aeec727183e7580443dfeb8556cbf1978d162"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.9'",
+ "version": "==1.1.2"
+ },
+ "numpy": {
+ "hashes": [
+ "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff",
+ "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47",
+ "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84",
+ "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d",
+ "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6",
+ "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f",
+ "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b",
+ "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49",
+ "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163",
+ "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571",
+ "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42",
+ "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff",
+ "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491",
+ "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4",
+ "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566",
+ "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf",
+ "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40",
+ "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd",
+ "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06",
+ "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282",
+ "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680",
+ "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db",
+ "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3",
+ "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90",
+ "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1",
+ "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289",
+ "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab",
+ "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c",
+ "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d",
+ "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb",
+ "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d",
+ "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a",
+ "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf",
+ "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1",
+ "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2",
+ "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a",
+ "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543",
+ "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00",
+ "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c",
+ "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f",
+ "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd",
+ "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868",
+ "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303",
+ "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83",
+ "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3",
+ "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d",
+ "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87",
+ "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa",
+ "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f",
+ "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae",
+ "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda",
+ "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915",
+ "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249",
+ "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de",
+ "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8"
+ ],
+ "markers": "python_version >= '3.10'",
+ "version": "==2.2.6"
+ },
+ "packaging": {
+ "hashes": [
+ "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f",
+ "sha256:f042152b681c4bfac5cae2742a55e103d27ab2ec0f3d88037136b6bfe7c9c5de"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==26.1"
+ },
+ "pandas": {
+ "hashes": [
+ "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7",
+ "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593",
+ "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5",
+ "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791",
+ "sha256:23ebd657a4d38268c7dfbdf089fbc31ea709d82e4923c5ffd4fbd5747133ce73",
+ "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec",
+ "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4",
+ "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5",
+ "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac",
+ "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084",
+ "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c",
+ "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87",
+ "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35",
+ "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250",
+ "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c",
+ "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826",
+ "sha256:5554c929ccc317d41a5e3d1234f3be588248e61f08a74dd17c9eabb535777dc9",
+ "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713",
+ "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1",
+ "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523",
+ "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3",
+ "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78",
+ "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53",
+ "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c",
+ "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21",
+ "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5",
+ "sha256:854d00d556406bffe66a4c0802f334c9ad5a96b4f1f868adf036a21b11ef13ff",
+ "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45",
+ "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110",
+ "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493",
+ "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b",
+ "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450",
+ "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86",
+ "sha256:a637c5cdfa04b6d6e2ecedcb81fc52ffb0fd78ce2ebccc9ea964df9f658de8c8",
+ "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98",
+ "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89",
+ "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66",
+ "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b",
+ "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8",
+ "sha256:bf1f8a81d04ca90e32a0aceb819d34dbd378a98bf923b6398b9a3ec0bf44de29",
+ "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6",
+ "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc",
+ "sha256:c503ba5216814e295f40711470446bc3fd00f0faea8a086cbc688808e26f92a2",
+ "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788",
+ "sha256:d3e28b3e83862ccf4d85ff19cf8c20b2ae7e503881711ff2d534dc8f761131aa",
+ "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151",
+ "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838",
+ "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b",
+ "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a",
+ "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d",
+ "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908",
+ "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0",
+ "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b",
+ "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c",
+ "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.9'",
+ "version": "==2.3.3"
+ },
+ "pastedeploy": {
+ "hashes": [
+ "sha256:76388ad53a661448d436df28c798063108f70e994ddc749540d733cdbd1b38cf",
+ "sha256:9ddbaf152f8095438a9fe81f82c78a6714b92ae8e066bed418b6a7ff6a095a95"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==3.1.0"
+ },
+ "plaster": {
+ "hashes": [
+ "sha256:42992ab1f4865f1278e2ad740e8ad145683bb4022e03534265528f0c23c0df2d",
+ "sha256:f8befc54bf8c1147c10ab40297ec84c2676fa2d4ea5d6f524d9436a80074ef98"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==1.1.2"
+ },
+ "plaster-pastedeploy": {
+ "hashes": [
+ "sha256:ad3550cc744648969ed3b810f33c9344f515ee8d8a8cec18e8f2c4a643c2181f",
+ "sha256:be262e6d2e41a7264875daa2fe2850cbb0615728bcdc92828fdc72736e381412"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==1.0.1"
+ },
+ "platformdirs": {
+ "hashes": [
+ "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a",
+ "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917"
+ ],
+ "markers": "python_version >= '3.10'",
+ "version": "==4.9.6"
+ },
+ "pluggy": {
+ "hashes": [
+ "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3",
+ "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==1.6.0"
+ },
+ "pygments": {
+ "hashes": [
+ "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f",
+ "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==2.20.0"
+ },
+ "pyparsing": {
+ "hashes": [
+ "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d",
+ "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.9'",
+ "version": "==3.3.2"
+ },
+ "pyproject-api": {
+ "hashes": [
+ "sha256:40c6f2d82eebdc4afee61c773ed208c04c19db4c4a60d97f8d7be3ebc0bbb330",
+ "sha256:8757c41a79c0f4ab71b99abed52b97ecf66bd20b04fa59da43b5840bac105a09"
+ ],
+ "markers": "python_version >= '3.10'",
+ "version": "==1.10.0"
+ },
+ "pyramid": {
+ "hashes": [
+ "sha256:0aa62604221f6a8ac6e77a0faa02a5b7a294d6675f15581d8d416dffe2ac98e7",
+ "sha256:5a24bc1b5f9e0f0d1c0b6ddd1111e84c15dac44a07e3c1d24e74dd9bb4fc22eb"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.10'",
+ "version": "==2.1"
+ },
+ "pytest": {
+ "hashes": [
+ "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9",
+ "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.10'",
+ "version": "==9.0.3"
+ },
+ "pytest-cov": {
+ "hashes": [
+ "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2",
+ "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.9'",
+ "version": "==7.1.0"
+ },
+ "pytest-django": {
+ "hashes": [
+ "sha256:3ff300c49f8350ba2953b90297d23bf5f589db69545f56f1ec5f8cff5da83e85",
+ "sha256:df94ec819a83c8979c8f6de13d9cdfbe76e8c21d39473cfe2b40c9fc9be3c758"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.10'",
+ "version": "==4.12.0"
+ },
+ "pytest-twisted": {
+ "hashes": [
+ "sha256:37e150cbbc0edba6592d36c53f44fc1196f3a9e93e7bef6a25bb10d9963f7f3e",
+ "sha256:f2e3f3f6f12f78df17c028fe16d87af09c76b95a7a85bc378b2d3e73a086e81a"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
+ "version": "==1.14.3"
+ },
+ "python-dateutil": {
+ "hashes": [
+ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
+ "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
+ ],
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
+ "version": "==2.9.0.post0"
+ },
+ "python-discovery": {
+ "hashes": [
+ "sha256:876e9c57139eb757cb5878cbdd9ae5379e5d96266c99ef731119e04fffe533bb",
+ "sha256:e1ae95d9af875e78f15e19aed0c6137ab1bb49c200f21f5061786490c9585c7a"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==1.2.2"
+ },
+ "python-subunit": {
+ "hashes": [
+ "sha256:254f85a144d8c4e62bf02cc53c834d2f36177056353fcd90a60a2745e229cf17",
+ "sha256:a57d61f0ba2c0a8657c61329301ada6ad8e30b26fb47ca3bb37481463e75aabf"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.10'",
+ "version": "==1.4.5"
+ },
+ "pytz": {
+ "hashes": [
+ "sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1",
+ "sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a"
+ ],
+ "version": "==2026.1.post1"
+ },
+ "pyyaml": {
+ "hashes": [
+ "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c",
+ "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a",
+ "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3",
+ "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956",
+ "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6",
+ "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c",
+ "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65",
+ "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a",
+ "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0",
+ "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b",
+ "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1",
+ "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6",
+ "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7",
+ "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e",
+ "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007",
+ "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310",
+ "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4",
+ "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9",
+ "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295",
+ "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea",
+ "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0",
+ "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e",
+ "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac",
+ "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9",
+ "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7",
+ "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35",
+ "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb",
+ "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b",
+ "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69",
+ "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5",
+ "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b",
+ "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c",
+ "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369",
+ "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd",
+ "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824",
+ "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198",
+ "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065",
+ "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c",
+ "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c",
+ "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764",
+ "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196",
+ "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b",
+ "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00",
+ "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac",
+ "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8",
+ "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e",
+ "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28",
+ "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3",
+ "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5",
+ "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4",
+ "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b",
+ "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf",
+ "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5",
+ "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702",
+ "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8",
+ "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788",
+ "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da",
+ "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d",
+ "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc",
+ "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c",
+ "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba",
+ "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f",
+ "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917",
+ "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5",
+ "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26",
+ "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f",
+ "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b",
+ "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be",
+ "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c",
+ "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3",
+ "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6",
+ "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926",
+ "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.8'",
+ "version": "==6.0.3"
+ },
+ "pyzmq": {
+ "hashes": [
+ "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d",
+ "sha256:01f9437501886d3a1dd4b02ef59fb8cc384fa718ce066d52f175ee49dd5b7ed8",
+ "sha256:03ff0b279b40d687691a6217c12242ee71f0fba28bf8626ff50e3ef0f4410e1e",
+ "sha256:05b12f2d32112bf8c95ef2e74ec4f1d4beb01f8b5e703b38537f8849f92cb9ba",
+ "sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581",
+ "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05",
+ "sha256:08e90bb4b57603b84eab1d0ca05b3bbb10f60c1839dc471fc1c9e1507bef3386",
+ "sha256:0c996ded912812a2fcd7ab6574f4ad3edc27cb6510349431e4930d4196ade7db",
+ "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28",
+ "sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e",
+ "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea",
+ "sha256:18339186c0ed0ce5835f2656cdfb32203125917711af64da64dbaa3d949e5a1b",
+ "sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066",
+ "sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97",
+ "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0",
+ "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113",
+ "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92",
+ "sha256:1f8426a01b1c4098a750973c37131cf585f61c7911d735f729935a0c701b68d3",
+ "sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86",
+ "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd",
+ "sha256:346e9ba4198177a07e7706050f35d733e08c1c1f8ceacd5eb6389d653579ffbc",
+ "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233",
+ "sha256:3970778e74cb7f85934d2b926b9900e92bfe597e62267d7499acc39c9c28e345",
+ "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31",
+ "sha256:448f9cb54eb0cee4732b46584f2710c8bc178b0e5371d9e4fc8125201e413a74",
+ "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc",
+ "sha256:49d3980544447f6bd2968b6ac913ab963a49dcaa2d4a2990041f16057b04c429",
+ "sha256:4a19387a3dddcc762bfd2f570d14e2395b2c9701329b266f83dd87a2b3cbd381",
+ "sha256:4c618fbcd069e3a29dcd221739cacde52edcc681f041907867e0f5cc7e85f172",
+ "sha256:50081a4e98472ba9f5a02850014b4c9b629da6710f8f14f3b15897c666a28f1b",
+ "sha256:507b6f430bdcf0ee48c0d30e734ea89ce5567fd7b8a0f0044a369c176aa44556",
+ "sha256:508e23ec9bc44c0005c4946ea013d9317ae00ac67778bd47519fdf5a0e930ff4",
+ "sha256:510869f9df36ab97f89f4cff9d002a89ac554c7ac9cadd87d444aa4cf66abd27",
+ "sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c",
+ "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd",
+ "sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e",
+ "sha256:677e744fee605753eac48198b15a2124016c009a11056f93807000ab11ce6526",
+ "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e",
+ "sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f",
+ "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128",
+ "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96",
+ "sha256:722ea791aa233ac0a819fc2c475e1292c76930b31f1d828cb61073e2fe5e208f",
+ "sha256:726b6a502f2e34c6d2ada5e702929586d3ac948a4dbbb7fed9854ec8c0466027",
+ "sha256:753d56fba8f70962cd8295fb3edb40b9b16deaa882dd2b5a3a2039f9ff7625aa",
+ "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f",
+ "sha256:7be883ff3d722e6085ee3f4afc057a50f7f2e0c72d289fd54df5706b4e3d3a50",
+ "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c",
+ "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2",
+ "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146",
+ "sha256:849ca054d81aa1c175c49484afaaa5db0622092b5eccb2055f9f3bb8f703782d",
+ "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97",
+ "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5",
+ "sha256:9541c444cfe1b1c0156c5c86ece2bb926c7079a18e7b47b0b1b3b1b875e5d098",
+ "sha256:96c71c32fff75957db6ae33cd961439f386505c6e6b377370af9b24a1ef9eafb",
+ "sha256:9a916f76c2ab8d045b19f2286851a38e9ac94ea91faf65bd64735924522a8b32",
+ "sha256:9c1790386614232e1b3a40a958454bdd42c6d1811837b15ddbb052a032a43f62",
+ "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf",
+ "sha256:a1aa0ee920fb3825d6c825ae3f6c508403b905b698b6460408ebd5bb04bbb312",
+ "sha256:a5b42d7a0658b515319148875fcb782bbf118dd41c671b62dae33666c2213bda",
+ "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540",
+ "sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604",
+ "sha256:ad68808a61cbfbbae7ba26d6233f2a4aa3b221de379ce9ee468aa7a83b9c36b0",
+ "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db",
+ "sha256:b1267823d72d1e40701dcba7edc45fd17f71be1285557b7fe668887150a14b78",
+ "sha256:b2e592db3a93128daf567de9650a2f3859017b3f7a66bc4ed6e4779d6034976f",
+ "sha256:b721c05d932e5ad9ff9344f708c96b9e1a485418c6618d765fca95d4daacfbef",
+ "sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2",
+ "sha256:bd67e7c8f4654bef471c0b1ca6614af0b5202a790723a58b79d9584dc8022a78",
+ "sha256:bf7b38f9fd7b81cb6d9391b2946382c8237fd814075c6aa9c3b746d53076023b",
+ "sha256:c0bb87227430ee3aefcc0ade2088100e528d5d3298a0a715a64f3d04c60ba02f",
+ "sha256:c17e03cbc9312bee223864f1a2b13a99522e0dc9f7c5df0177cd45210ac286e6",
+ "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39",
+ "sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f",
+ "sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355",
+ "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a",
+ "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a",
+ "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856",
+ "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9",
+ "sha256:da96ecdcf7d3919c3be2de91a8c513c186f6762aa6cf7c01087ed74fad7f0968",
+ "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7",
+ "sha256:dd2fec2b13137416a1c5648b7009499bcc8fea78154cd888855fa32514f3dad1",
+ "sha256:df7cd397ece96cf20a76fae705d40efbab217d217897a5053267cd88a700c266",
+ "sha256:e2687c2d230e8d8584fbea433c24382edfeda0c60627aca3446aa5e58d5d1831",
+ "sha256:e30a74a39b93e2e1591b58eb1acef4902be27c957a8720b0e368f579b82dc22f",
+ "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7",
+ "sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394",
+ "sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07",
+ "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496",
+ "sha256:f328d01128373cb6763823b2b4e7f73bdf767834268c565151eacb3b7a392f90",
+ "sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271",
+ "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6",
+ "sha256:ff8d114d14ac671d88c89b9224c63d6c4e5a613fe8acd5594ce53d752a3aafe9"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.8'",
+ "version": "==27.1.0"
+ },
+ "requests": {
+ "hashes": [
+ "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517",
+ "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a"
+ ],
+ "markers": "python_version >= '3.10'",
+ "version": "==2.33.1"
+ },
+ "requests-file": {
+ "hashes": [
+ "sha256:d0f5eb94353986d998f80ac63c7f146a307728be051d4d1cd390dbdb59c10fa2",
+ "sha256:f14243d7796c588f3521bd423c5dea2ee4cc730e54a3cac9574d78aca1272576"
+ ],
+ "version": "==3.0.1"
+ },
+ "requests-toolbelt": {
+ "hashes": [
+ "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6",
+ "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"
+ ],
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+ "version": "==1.0.0"
+ },
+ "setuptools": {
+ "hashes": [
+ "sha256:487b53915f52501f0a79ccfd0c02c165ffe06631443a886740b91af4b7a5845a",
+ "sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==81.0.0"
+ },
+ "six": {
+ "hashes": [
+ "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274",
+ "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"
+ ],
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
+ "version": "==1.17.0"
+ },
+ "soupsieve": {
+ "hashes": [
+ "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349",
+ "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==2.8.3"
+ },
+ "sqlalchemy": {
+ "hashes": [
+ "sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72",
+ "sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe",
+ "sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75",
+ "sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5",
+ "sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148",
+ "sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7",
+ "sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e",
+ "sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518",
+ "sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7",
+ "sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700",
+ "sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717",
+ "sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672",
+ "sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88",
+ "sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f",
+ "sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f",
+ "sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08",
+ "sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a",
+ "sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3",
+ "sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b",
+ "sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536",
+ "sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0",
+ "sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b",
+ "sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a",
+ "sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3",
+ "sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4",
+ "sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339",
+ "sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158",
+ "sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066",
+ "sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662",
+ "sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1",
+ "sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3",
+ "sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5",
+ "sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01",
+ "sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613",
+ "sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a",
+ "sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0",
+ "sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f",
+ "sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a",
+ "sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e",
+ "sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2",
+ "sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af",
+ "sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014",
+ "sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33",
+ "sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61",
+ "sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d",
+ "sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187",
+ "sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401",
+ "sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b",
+ "sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d",
+ "sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f",
+ "sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba",
+ "sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977",
+ "sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a",
+ "sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe",
+ "sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b",
+ "sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f",
+ "sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1",
+ "sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4",
+ "sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d",
+ "sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120",
+ "sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750",
+ "sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0",
+ "sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.7'",
+ "version": "==2.0.49"
+ },
+ "sqlparse": {
+ "hashes": [
+ "sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba",
+ "sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==0.5.5"
+ },
+ "suds-community": {
+ "hashes": [
+ "sha256:505b191865bca125f12e8ff9598b24d9c0108b98826671bdd700ed51def44e36",
+ "sha256:ab3b24dc9ba06b5e6598e2a5d34d2a7d06c79e613d81cedc028475bfbd3bb90c"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.7'",
+ "version": "==1.2.0"
+ },
+ "testtools": {
+ "hashes": [
+ "sha256:32e2f96be68e2a0ed8a3ad14d9923848b8a53cbd2eaf6c3b2a2061753f8ab7c3",
+ "sha256:eb562d1a2157c6d443c8c118861eb452b3655d1842f9b61b8567ad01b32826e3"
+ ],
+ "markers": "python_version >= '3.10'",
+ "version": "==2.9.0"
+ },
+ "tomli": {
+ "hashes": [
+ "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853",
+ "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe",
+ "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5",
+ "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d",
+ "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd",
+ "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26",
+ "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54",
+ "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6",
+ "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c",
+ "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a",
+ "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd",
+ "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f",
+ "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5",
+ "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9",
+ "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662",
+ "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9",
+ "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1",
+ "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585",
+ "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e",
+ "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c",
+ "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41",
+ "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f",
+ "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085",
+ "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15",
+ "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7",
+ "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c",
+ "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36",
+ "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076",
+ "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac",
+ "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8",
+ "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232",
+ "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece",
+ "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a",
+ "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897",
+ "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d",
+ "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4",
+ "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917",
+ "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396",
+ "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a",
+ "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc",
+ "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba",
+ "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f",
+ "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257",
+ "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30",
+ "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf",
+ "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9",
+ "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==2.4.1"
+ },
+ "tomli-w": {
+ "hashes": [
+ "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90",
+ "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==1.2.0"
+ },
+ "tox": {
+ "hashes": [
+ "sha256:62c780e42f87d34ee60f2ea20342156253794fdcbd6885fd797d98ee05009f22",
+ "sha256:cc4e716d18c4889aa179d785175c438fa60c35deef20ce689ec288d8fb656096"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.10'",
+ "version": "==4.53.0"
+ },
+ "translationstring": {
+ "hashes": [
+ "sha256:5f4dc4d939573db851c8d840551e1a0fb27b946afe3b95aafc22577eed2d6262",
+ "sha256:bf947538d76e69ba12ab17283b10355a9ecfbc078e6123443f43f2107f6376f3"
+ ],
+ "version": "==1.4"
+ },
+ "twisted": {
+ "hashes": [
+ "sha256:1deb272358cb6be1e3e8fc6f9c8b36f78eb0fa7c2233d2dbe11ec6fee04ea316",
+ "sha256:8559f654d01a54a8c3efe66d533d43f383531ebf8d81d9f9ab4769d91ca15df7"
+ ],
+ "index": "pypi",
+ "markers": "python_full_version >= '3.8.0'",
+ "version": "==25.5.0"
+ },
+ "typing-extensions": {
+ "hashes": [
+ "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466",
+ "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==4.15.0"
+ },
+ "tzdata": {
+ "hashes": [
+ "sha256:4b1d2be7ac37ceafd7327b961aa3a54e467efbdb563a23655fbfe0d39cfc42a9",
+ "sha256:67658a1903c75917309e753fdc349ac0efd8c27db7a0cb406a25be4840f87f98"
+ ],
+ "markers": "python_version >= '2'",
+ "version": "==2026.1"
+ },
+ "urllib3": {
+ "hashes": [
+ "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed",
+ "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==2.6.3"
+ },
+ "venusian": {
+ "hashes": [
+ "sha256:0845808a985976acbceaa1fbb871c7fac4fb28ae75453232970e9c2c2866dbf4",
+ "sha256:534fb3b355669283eb3954581931e5d1d071fce61d029d58f3219a5e3a6f0c41"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==3.1.1"
+ },
+ "virtualenv": {
+ "hashes": [
+ "sha256:29d21e941795206138d0f22f4e45ff7050e5da6c6472299fb7103318763861ac",
+ "sha256:b294ef68192638004d72524ce7ef303e9d0cf5a44c95ce2e54a7500a6381cada"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==21.2.4"
+ },
+ "waitress": {
+ "hashes": [
+ "sha256:682aaaf2af0c44ada4abfb70ded36393f0e307f4ab9456a215ce0020baefc31f",
+ "sha256:c56d67fd6e87c2ee598b76abdd4e96cfad1f24cacdea5078d382b1f9d7b5ed2e"
+ ],
+ "markers": "python_full_version >= '3.9.0'",
+ "version": "==3.0.2"
+ },
+ "webob": {
+ "hashes": [
+ "sha256:45e34c58ed0c7e2ecd238ffd34432487ff13d9ad459ddfd77895e67abba7c1f9",
+ "sha256:ad6078e2edb6766d1334ec3dee072ac6a7f95b1e32ce10def8ff7f0f02d56589"
+ ],
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
+ "version": "==1.8.9"
+ },
+ "webtest": {
+ "hashes": [
+ "sha256:2f51a0844f3a8beaef89bc23d225fe05ad816f7e429ffcc655a13013a799ac6c",
+ "sha256:7aeab50f970d46c068e7a36dd162cb242591edf72a1d04efd21374772b931741"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.9'",
+ "version": "==3.0.7"
+ },
+ "werkzeug": {
+ "hashes": [
+ "sha256:63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50",
+ "sha256:9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.9'",
+ "version": "==3.1.8"
+ },
+ "zeep": {
+ "hashes": [
+ "sha256:1a23a667ce9d73a0dbfdf15745bfa2b7ab0b6402135c0cd5067574838398e0e6",
+ "sha256:ed08c3179709172bfaaa9b76a6a545f8a57043ec6218e64e9deb81ff1e0ff79b"
+ ],
+ "index": "pypi",
+ "markers": "python_version >= '3.8'",
+ "version": "==4.3.2"
+ },
+ "zope-interface": {
+ "hashes": [
+ "sha256:12a33bb596ca20520e44f97918950cfc66a632ac0278a7f40608217cc4269948",
+ "sha256:1aa0e1d72212cedc38b2156bbca08cf24625c057135a7947ef6b19bc732b2772",
+ "sha256:301db4049c79a15a3b29d89795e150daf0e9ae701404b112ad6585ea863f6ef5",
+ "sha256:33a13acba79ef693fb64ceb6193ece913d39586f184797f133c1bc549da86851",
+ "sha256:34d6c10fa790005487c471e0e4ab537b0fa9a70e55a96994e51ffeef92205fa4",
+ "sha256:3853bfb808084e1b4a3a769b00bd8b58a52b0c4a4fc5c23de26d283cd8beb627",
+ "sha256:54ab83218a8f6947ba4b6cb1a121f1e1abe2e418b838ccdac71639d0f97e734e",
+ "sha256:568b97cb701fd2830b52198a2885e851317a019e1912eaad107860e3cca71964",
+ "sha256:5a5b50d0dcdb4200f1936f75b6688bd86de5c14c5d20bed2e004300a04521826",
+ "sha256:5e9861493457268f923d8aae4052383922162c3d56094c4e3a9ff83173d64be3",
+ "sha256:62839e4201869a29f99742df7f7139cac4ce301850d3787da37f84e271ad9b95",
+ "sha256:731eaf0a0f2a683315a2dfc2953ef831ae51e062b87cff6220e0e5102a83b612",
+ "sha256:8ce49d43366e12aeccd14fcaebb3ef110f50f5795e0d4a95383ea057365cedf2",
+ "sha256:8f81d90f80b9fbf36602549e2f187861c9d7139837f8c9dd685ce3b933c6360f",
+ "sha256:93108d5f8dee20177a637438bf4df4c6faf8a317c9d4a8b1d5e78123854e3317",
+ "sha256:96106a5f609bb355e1aec6ab0361213c8af0843ca1e1ba9c42eacfbd0910914e",
+ "sha256:961af756797e36c1e77f7d0dc8ac1322de0c071eaa1a641dbe3b790061968dd9",
+ "sha256:96f0001b49227d756770fc70ecde49f19332ae98ec98e1bbbf2fd7a87e9d4e45",
+ "sha256:99c84e12efe0e17f03c6bb5a8ea18fb2841e6666ee0b8331d5967fec84337884",
+ "sha256:a6329f296b70f62043bf2df06eb91b4be040baee32ec4a3e0314f3893fa5c51c",
+ "sha256:a918f8e73c35a1352a4b49db67b90b37d33fb7651c834def3f0e3784437bb3a8",
+ "sha256:b361b7ce566bc024e55f74eb1e88afc14039d7bd8ea13eeff3b7a8400dc59683",
+ "sha256:c8a2f9c4ee0f2ad4817e9481684993d33b66d9b815f9157a716a189af483bc34",
+ "sha256:d287183767926bc9841e51471a28b77c7b49fddf65016aa7faf5a1447e2b6558",
+ "sha256:e1a9de7d0b5b5c249a73b91aebf4598ce05e334303af6aa94865893283e9ff10",
+ "sha256:e8964f1a13b07c8770eab88b7a6cd0870c3e36442e4ef4937f36fd0b6d1cea2c",
+ "sha256:e9f7e4b46741a11a9e1fab8b68710f08dec700e9f1b877cdca02480fbebe4846",
+ "sha256:ec2728e3cf685126ccd2e0f7635fb60edf116f76f402dd66f4df13d9d9348b4b",
+ "sha256:f420f6c96307ff265981c510782f0ed97475107b78ca9fca0bb04fe36f363eb4",
+ "sha256:f5be73ca1304daa3046ee5835f7fa6b3badadf02102b570532dd57cd25dd72d6",
+ "sha256:ffeae9102aa6ba5bd2f9a547016347bd87c9cf01aea564936c0d165fff0b1242"
+ ],
+ "markers": "python_version >= '3.10'",
+ "version": "==8.3"
+ },
+ "zope.deprecation": {
+ "hashes": [
+ "sha256:18727ebda8e63a6d4bd28a290e8b46852e9f14473debb5cc40a0a2dccfadf15f",
+ "sha256:ff72d51c88b516b9ddf2cfb826381cc49f99a6a89b7d35c97faca7bee3b46da6"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==6.0"
+ }
+ }
+}
diff --git a/examples/authentication/http_cookie/server_soap.py b/examples/authentication/http_cookie/server_soap.py
index 426f56704..47c9e0cbb 100755
--- a/examples/authentication/http_cookie/server_soap.py
+++ b/examples/authentication/http_cookie/server_soap.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-#encoding: utf8
+# encoding: utf8
#
# Copyright © Burak Arslan ,
# Arskom Ltd. http://www.arskom.com.tr
@@ -36,7 +36,7 @@
from pprint import pformat
-from spyne.util.six.moves.http_cookies import SimpleCookie
+from http.cookies import SimpleCookie
# bcrypt seems to be among the latest consensus around cryptograpic circles on
# storing passwords.
@@ -45,7 +45,7 @@
try:
import bcrypt
except ImportError:
- print('easy_install --user py-bcrypt to get it.')
+ print("easy_install --user py-bcrypt to get it.")
raise
from spyne import Unicode, Application, rpc, Service
@@ -56,46 +56,47 @@
class PublicKeyError(Fault):
- __namespace__ = 'spyne.examples.authentication'
+ __namespace__ = "spyne.examples.authentication"
def __init__(self, value):
super(PublicKeyError, self).__init__(
- faultcode='Client.KeyError',
- faultstring='Value %r not found' % value
- )
+ faultcode="Client.KeyError", faultstring="Value %r not found" % value
+ )
class AuthenticationError(Fault):
- __namespace__ = 'spyne.examples.authentication'
+ __namespace__ = "spyne.examples.authentication"
def __init__(self, user_name):
# TODO: self.transport.http.resp_code = HTTP_401
super(AuthenticationError, self).__init__(
- faultcode='Client.AuthenticationError',
- faultstring='Invalid authentication request for %r' % user_name
- )
+ faultcode="Client.AuthenticationError",
+ faultstring="Invalid authentication request for %r" % user_name,
+ )
class AuthorizationError(Fault):
- __namespace__ = 'spyne.examples.authentication'
+ __namespace__ = "spyne.examples.authentication"
def __init__(self):
# TODO: self.transport.http.resp_code = HTTP_401
super(AuthorizationError, self).__init__(
- faultcode='Client.AuthorizationError',
- faultstring='You are not authorized to access this resource.'
- )
+ faultcode="Client.AuthorizationError",
+ faultstring="You are not authorized to access this resource.",
+ )
+
class UnauthenticatedError(Fault):
- __namespace__ = 'spyne.examples.authentication'
+ __namespace__ = "spyne.examples.authentication"
def __init__(self):
super(UnauthenticatedError, self).__init__(
- faultcode='Client.UnauthenticatedError',
- faultstring='This resource can only be accessed after authentication.'
- )
+ faultcode="Client.UnauthenticatedError",
+ faultstring="This resource can only be accessed after authentication.",
+ )
+
class SpyneDict(dict):
def __getitem__(self, key):
@@ -106,33 +107,35 @@ def __getitem__(self, key):
class Preferences(ComplexModel):
- __namespace__ = 'spyne.examples.authentication'
+ __namespace__ = "spyne.examples.authentication"
language = String(max_len=2)
time_zone = String
user_db = {
- 'neo': bcrypt.hashpw(b'Wh1teR@bbit', bcrypt.gensalt()),
+ "neo": bcrypt.hashpw(b"Wh1teR@bbit", bcrypt.gensalt()),
}
session_db = set()
-preferences_db = SpyneDict({
- 'neo': Preferences(language='en', time_zone='Underground/Zion'),
- 'smith': Preferences(language='xx', time_zone='Matrix/Core'),
-})
+preferences_db = SpyneDict(
+ {
+ "neo": Preferences(language="en", time_zone="Underground/Zion"),
+ "smith": Preferences(language="xx", time_zone="Matrix/Core"),
+ }
+)
class Encoding:
- SESSION_ID = 'ascii'
- USER_NAME = PASSWORD = CREDENTIALS = 'utf8'
+ SESSION_ID = "ascii"
+ USER_NAME = PASSWORD = CREDENTIALS = "utf8"
class UserService(Service):
- __tns__ = 'spyne.examples.authentication'
+ __tns__ = "spyne.examples.authentication"
- @rpc(M(Unicode), M(Unicode), _throws=AuthenticationError)
+ @rpc(M(Unicode), M(Unicode), _throws=AuthenticationError)
def authenticate(ctx, user_name, password):
ENC_C = Encoding.CREDENTIALS
ENC_SID = Encoding.SESSION_ID
@@ -140,13 +143,13 @@ def authenticate(ctx, user_name, password):
password_hash = user_db.get(user_name, None)
if password_hash is None:
- raise AuthenticationError(user_name)
+ raise AuthenticationError(user_name)
password_b = password.encode(ENC_C)
if bcrypt.hashpw(password_b, password_hash) != password_hash:
- raise AuthenticationError(user_name)
+ raise AuthenticationError(user_name)
- session_id = '%x' % (random.randint(1<<128, (1<<132)-1))
+ session_id = "%x" % (random.randint(1 << 128, (1 << 132) - 1))
session_key = (
user_name.encode(ENC_C),
session_id.encode(ENC_SID),
@@ -154,9 +157,9 @@ def authenticate(ctx, user_name, password):
session_db.add(session_key)
cookie = SimpleCookie()
- cookie["session-id"] = \
- base64.urlsafe_b64encode(b"\0".join(session_key)) \
- .decode('ascii') # find out how to do urlsafe_b64encodestring
+ cookie["session-id"] = base64.urlsafe_b64encode(b"\0".join(session_key)).decode(
+ "ascii"
+ ) # find out how to do urlsafe_b64encodestring
cookie["session-id"]["max-age"] = 3600
header_name, header_value = cookie.output().split(":", 1)
@@ -164,7 +167,6 @@ def authenticate(ctx, user_name, password):
logging.debug("Response headers: %s", pformat(ctx.transport.resp_headers))
-
@rpc(M(String), _throws=PublicKeyError, _returns=Preferences)
def get_preferences(ctx, user_name):
# Only allow access to the users own preferences.
@@ -193,8 +195,7 @@ def _on_method_call(ctx):
session_cookie = cookie["session-id"].value
- user_name, session_id = base64.urlsafe_b64decode(session_cookie) \
- .split(b"\0", 1)
+ user_name, session_id = base64.urlsafe_b64decode(session_cookie).split(b"\0", 1)
session_id = tuple(base64.urlsafe_b64decode(session_cookie).split(b"\0", 1))
if not session_id in session_db:
@@ -203,26 +204,27 @@ def _on_method_call(ctx):
ctx.udc = session_id[0].decode(Encoding.USER_NAME)
-UserService.event_manager.add_listener('method_call', _on_method_call)
+UserService.event_manager.add_listener("method_call", _on_method_call)
-if __name__=='__main__':
+if __name__ == "__main__":
from spyne.util.wsgi_wrapper import run_twisted
logging.basicConfig(level=logging.DEBUG)
- logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
- logging.getLogger('twisted').setLevel(logging.DEBUG)
-
- application = Application([UserService],
- tns='spyne.examples.authentication',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11()
+ logging.getLogger("spyne.protocol.xml").setLevel(logging.DEBUG)
+ logging.getLogger("twisted").setLevel(logging.DEBUG)
+
+ application = Application(
+ [UserService],
+ tns="spyne.examples.authentication",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
)
wsgi_app = WsgiApplication(application)
wsgi_app.doc.wsdl11.xsl_href = "wsdl-viewer.xsl"
twisted_apps = [
- (wsgi_app, b'app'),
+ (wsgi_app, b"app"),
]
sys.exit(run_twisted(twisted_apps, 8000))
diff --git a/examples/custom_type.py b/examples/custom_type.py
index 415e4071e..551e545da 100644
--- a/examples/custom_type.py
+++ b/examples/custom_type.py
@@ -31,7 +31,6 @@
from spyne import ComplexModel, AnyDict, ValidationError, Array, Any
-from spyne.util import six
from spyne.util.dictdoc import json_loads
from spyne.util.web import log_repr
@@ -41,7 +40,7 @@ class DictOfUniformArray(AnyDict):
@staticmethod
def validate_native(cls, inst):
for k, v in inst.items():
- if not isinstance(k, six.string_types):
+ if not isinstance(k, str):
raise ValidationError(type(k), "Invalid key type %r")
if not isinstance(v, list):
raise ValidationError(type(v), "Invalid value type %r")
diff --git a/examples/django/rpctest/urls.py b/examples/django/rpctest/urls.py
index c909e8849..1670cde18 100644
--- a/examples/django/rpctest/urls.py
+++ b/examples/django/rpctest/urls.py
@@ -29,22 +29,33 @@
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
-from django.conf.urls import url
+from django.urls import re_path
from spyne.protocol.soap import Soap11
from spyne.server.django import DjangoView
from rpctest.core.views import hello_world_service, app, HelloWorldService
-
urlpatterns = [
- url(r'^hello_world/', hello_world_service),
- url(r'^say_hello/', DjangoView.as_view(
- services=[HelloWorldService], tns='spyne.examples.django',
- in_protocol=Soap11(validator='lxml'), out_protocol=Soap11())),
- url(r'^say_hello_not_cached/', DjangoView.as_view(
- services=[HelloWorldService], tns='spyne.examples.django',
- in_protocol=Soap11(validator='lxml'), out_protocol=Soap11(),
- cache_wsdl=False)),
- url(r'^api/', DjangoView.as_view(application=app)),
+ re_path(r"^hello_world/", hello_world_service),
+ re_path(
+ r"^say_hello/",
+ DjangoView.as_view(
+ services=[HelloWorldService],
+ tns="spyne.examples.django",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
+ ),
+ ),
+ re_path(
+ r"^say_hello_not_cached/",
+ DjangoView.as_view(
+ services=[HelloWorldService],
+ tns="spyne.examples.django",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
+ cache_wsdl=False,
+ ),
+ ),
+ re_path(r"^api/", DjangoView.as_view(application=app)),
]
diff --git a/examples/msgpack_transport/client_json_document.py b/examples/msgpack_transport/client_json_document.py
index 151721340..b896d04dd 100755
--- a/examples/msgpack_transport/client_json_document.py
+++ b/examples/msgpack_transport/client_json_document.py
@@ -50,8 +50,6 @@
import json
import msgpack
-from spyne.util.six import BytesIO
-
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", 5551))
diff --git a/examples/msgpack_transport/client_msgpack_document.py b/examples/msgpack_transport/client_msgpack_document.py
index ea80fd388..dda7ada1d 100755
--- a/examples/msgpack_transport/client_msgpack_document.py
+++ b/examples/msgpack_transport/client_msgpack_document.py
@@ -48,8 +48,6 @@
import socket
import msgpack
-from spyne.util.six import BytesIO
-
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", 5550))
diff --git a/examples/xml/polymorphic_roundtrip.py b/examples/xml/polymorphic_roundtrip.py
index 75d49e39a..4dd5377f9 100644
--- a/examples/xml/polymorphic_roundtrip.py
+++ b/examples/xml/polymorphic_roundtrip.py
@@ -7,11 +7,8 @@
from lxml import etree
from spyne.interface.xml_schema.parser import hier_repr
-from spyne.util import six
from spyne import ComplexModel, Unicode
-from spyne.util.xml import get_object_as_xml_polymorphic, \
- get_xml_as_object_polymorphic
-
+from spyne.util.xml import get_object_as_xml_polymorphic, get_xml_as_object_polymorphic
# uncomment to see what's going on under the hood
# import logging
@@ -20,9 +17,9 @@
class B(ComplexModel):
- __namespace__ = 'some_ns'
+ __namespace__ = "some_ns"
_type_info = {
- '_b': Unicode,
+ "_b": Unicode,
}
def __init__(self):
@@ -31,9 +28,9 @@ def __init__(self):
class C(B):
- __namespace__ = 'some_ns'
+ __namespace__ = "some_ns"
_type_info = {
- '_c': Unicode,
+ "_c": Unicode,
}
def __init__(self):
@@ -42,25 +39,22 @@ def __init__(self):
class A(ComplexModel):
- __namespace__ = 'some_ns'
+ __namespace__ = "some_ns"
_type_info = {
- '_a': Unicode,
- '_b': B,
+ "_a": Unicode,
+ "_b": B,
}
def __init__(self, b=None):
super(A, self).__init__()
- self._a = 'a'
+ self._a = "a"
self._b = b
a = A(b=C())
elt = get_object_as_xml_polymorphic(a, A)
xml_string = etree.tostring(elt, pretty_print=True)
-if six.PY2:
- print(xml_string, end="")
-else:
- sys.stdout.buffer.write(xml_string)
+sys.stdout.buffer.write(xml_string)
element_tree = etree.fromstring(xml_string)
new_a = get_xml_as_object_polymorphic(elt, A)
diff --git a/examples/xml/utils_poly.py b/examples/xml/utils_poly.py
index 890122c61..a4a542b57 100755
--- a/examples/xml/utils_poly.py
+++ b/examples/xml/utils_poly.py
@@ -5,7 +5,6 @@
import sys
from lxml import etree
-from spyne.util import six
from spyne import ComplexModel, Unicode
from spyne.util.xml import get_object_as_xml_polymorphic
@@ -13,27 +12,24 @@
class B(ComplexModel):
_type_info = [
- ('_b', Unicode(default="b")),
+ ("_b", Unicode(default="b")),
]
class C(B):
_type_info = [
- ('_c', Unicode(default="c")),
+ ("_c", Unicode(default="c")),
]
class A(ComplexModel):
_type_info = [
- ('a', Unicode(subname="_a")),
- ('b', B.customize(subname="_b")),
+ ("a", Unicode(subname="_a")),
+ ("b", B.customize(subname="_b")),
]
a = A(b=C())
elt = get_object_as_xml_polymorphic(a, A, no_namespace=True)
xml_string = etree.tostring(elt, pretty_print=True)
-if six.PY2:
- print(xml_string, end="")
-else:
- sys.stdout.buffer.write(xml_string)
+sys.stdout.buffer.write(xml_string)
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 000000000..14b807c0c
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,68 @@
+[project]
+name = "spyne"
+version = "3.0.0"
+description = "A transport and architecture agnostic rpc library that focuses on exposing public services with a well-defined API."
+readme = "README.rst"
+keywords = [
+ "soap",
+ "wsdl",
+ "wsgi",
+ "zeromq",
+ "rest",
+ "rpc",
+ "json",
+ "http",
+ "msgpack",
+ "xml",
+ "django",
+ "pyramid",
+ "postgresql",
+ "sqlalchemy",
+ "twisted",
+ "yaml",
+]
+classifiers = [
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: Implementation :: CPython",
+ "Programming Language :: Python :: Implementation :: PyPy",
+ "Operating System :: OS Independent",
+ "Natural Language :: English",
+ "Development Status :: 5 - Production/Stable",
+ "Intended Audience :: Developers",
+ "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
+]
+requires-python = ">=3.10"
+dependencies = [
+ "pytz",
+]
+[[project.authors]]
+name = "Burak Arslan"
+email = "burak+package@spyne.io"
+
+[[project.maintainers]]
+name = "Burak Arslan"
+email = "burak+package@spyne.io"
+
+[project.license]
+text = "LGPL-2.1-or-later"
+
+[project.urls]
+Homepage = "http://spyne.io"
+
+[project.scripts]
+sort_wsdl = "spyne.test.sort_wsdl:main"
+
+[tool.isort]
+profile = "black"
+
+[tool.black]
+line-length = 88
+
+[tool.setuptools.packages.find]
+where = [
+ ".",
+]
diff --git a/pytest.ini b/pytest.ini
index 56711bbf7..5e1a8c17d 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -1,2 +1,8 @@
[pytest]
junit_family=xunit1
+norecursedirs = examples build
+filterwarnings =
+ ignore:.*was deprecated in Twisted.*:DeprecationWarning
+ ignore::UserWarning:pyramid.asset
+ ignore::DeprecationWarning:pkg_resources
+ ignore::sqlalchemy.exc.SAWarning
diff --git a/setup.py b/setup.py
deleted file mode 100755
index 2f29fc2c9..000000000
--- a/setup.py
+++ /dev/null
@@ -1,309 +0,0 @@
-#!/usr/bin/env python
-#encoding: utf8
-
-from __future__ import print_function
-
-import io
-import os
-import re
-import sys
-import inspect
-
-from glob import glob
-from itertools import chain
-from os.path import join, dirname, abspath
-
-from setuptools import setup
-from setuptools import find_packages
-from setuptools.command.test import test as TestCommand
-
-try:
- import colorama
- colorama.init()
- from colorama import Fore
- RESET = Fore.RESET
- GREEN = Fore.GREEN
- RED = Fore.RED
-except ImportError:
- RESET = ''
- GREEN = ''
- RED = ''
-
-IS_PYPY = '__pypy__' in sys.builtin_module_names
-OWN_PATH = abspath(inspect.getfile(inspect.currentframe()))
-EXAMPLES_DIR = join(dirname(OWN_PATH), 'examples')
-PYVER = ''.join([str(i) for i in sys.version_info[:2]])
-
-with io.open(os.path.join(os.path.dirname(__file__), 'spyne', '__init__.py'), 'r') as v:
- VERSION = re.match(r".*__version__ = '(.*?)'", v.read(), re.S).group(1)
-
-SHORT_DESC="A transport and architecture agnostic rpc library that focuses on" \
-" exposing public services with a well-defined API."
-
-LONG_DESC = """Homepage: http://spyne.io
-
-Spyne aims to save the protocol implementers the hassle of
-implementing their own remote procedure call api and the application programmers
-the hassle of jumping through hoops just to expose their services using multiple
-protocols and transports.
-"""
-
-try:
- os.stat('CHANGELOG.rst')
- with io.open('CHANGELOG.rst', 'rb') as f:
- LONG_DESC += u"\n\n" + f.read().decode('utf8')
-except OSError:
- pass
-
-
-###############################
-# Testing stuff
-
-def call_test(f, a, tests, env={}):
- import spyne.test
- from multiprocessing import Process, Queue
-
- tests_dir = os.path.dirname(spyne.test.__file__)
- if len(tests) > 0:
- a.extend(chain(*[glob(join(tests_dir, test)) for test in tests]))
-
- queue = Queue()
- p = Process(target=_wrapper(f), args=[a, queue, env])
- p.start()
- p.join()
-
- ret = queue.get()
- if ret == 0:
- print(tests or a, "OK")
- else:
- print(tests or a, "FAIL")
-
- print()
-
- return ret
-
-
-def _wrapper(f):
- import traceback
- def _(args, queue, env):
- print("env:", env)
- for k, v in env.items():
- os.environ[k] = v
- try:
- retval = f(args)
- except SystemExit as e:
- retval = e.code
- except BaseException as e:
- print(traceback.format_exc())
- retval = 1
-
- queue.put(retval)
-
- return _
-
-
-def run_tests_and_create_report(report_name, *tests, **kwargs):
- import spyne.test
- import pytest
-
- if os.path.isfile(report_name):
- os.unlink(report_name)
-
- tests_dir = os.path.dirname(spyne.test.__file__)
-
- args = [
- '--verbose',
- '--cov-report=', '--cov', 'spyne',
- '--cov-append',
- '--tb=short',
- '--junitxml=%s' % report_name,
- ]
- args.extend('--{0}={1}'.format(k, v) for k, v in kwargs.items())
- args.extend(chain(*[glob("%s/%s" % (tests_dir, test)) for test in tests]))
-
- return pytest.main(args)
-
-
-_ctr = 0
-
-
-def call_pytest(*tests, **kwargs):
- global _ctr
-
- _ctr += 1
- file_name = 'test_result.%d.xml' % _ctr
- os.environ['COVERAGE_FILE'] = '.coverage.%d' % _ctr
-
- return run_tests_and_create_report(file_name, *tests, **kwargs)
-
-
-def call_pytest_subprocess(*tests, **kwargs):
- global _ctr
- import pytest
-
- _ctr += 1
- file_name = 'test_result.%d.xml' % _ctr
- if os.path.isfile(file_name):
- os.unlink(file_name)
-
- # env = {'COVERAGE_FILE': '.coverage.%d' % _ctr}
- env = {}
-
- args = [
- '--verbose',
- '--cov-append',
- '--cov-report=',
- '--cov', 'spyne',
- '--tb=line',
- '--junitxml=%s' % file_name
- ]
- args.extend('--{0}={1}'.format(k, v) for k, v in kwargs.items())
- return call_test(pytest.main, args, tests, env)
-
-
-def call_tox_subprocess(env):
- import tox.session
-
- args = ['-e', env]
-
- return call_test(tox.session.main, args, [])
-
-def call_coverage():
- import coverage.cmdline
-
- # coverage.cmdline.main(['combine'])
- # call_test(coverage.cmdline.main, ['combine'], [])
- call_test(coverage.cmdline.main, ['xml', '-i'], [])
-
- return 0
-
-
-class ExtendedTestCommand(TestCommand):
- """TestCommand customized to project needs."""
-
- user_options = TestCommand.user_options + [
- ('capture=', 'k', "py.test output capture control (see py.test "
- "--capture)"),
- ]
-
- def initialize_options(self):
- TestCommand.initialize_options(self)
- self.capture = 'fd'
-
- def finalize_options(self):
- TestCommand.finalize_options(self)
-
- self.test_args = []
- self.test_suite = True
-
-
-class RunTests(ExtendedTestCommand):
- def run_tests(self):
- cfn = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),
- 'tox.ini')
- from collections import OrderedDict
- djenvs = tuple(OrderedDict(((k, None) for k in
- re.findall('py%s-dj[0-9]+' % PYVER,
- open(cfn, 'rb').read().decode('utf8')))).keys())
-
- ret = 0
- tests = [
- 'interface', 'model', 'multipython', 'protocol', 'util',
-
- 'interop/test_pyramid.py',
- 'interop/test_soap_client_http_twisted.py',
-
- 'transport/test_msgpack.py'
-
- 'test_null_server.py',
- 'test_service.py',
- 'test_soft_validation.py',
- 'test_sqlalchemy.py',
- 'test_sqlalchemy_deprecated.py',
- ]
-
- print("Test stage 1: Unit tests")
- ret = call_pytest_subprocess(*tests, capture=self.capture) or ret
-
- print("\nTest stage 2: End-to-end tests")
- ret = call_pytest_subprocess('interop/test_httprpc.py',
- capture=self.capture) or ret
- ret = call_pytest_subprocess('interop/test_soap_client_http.py',
- capture=self.capture) or ret
- ret = call_pytest_subprocess('interop/test_soap_client_zeromq.py',
- capture=self.capture) or ret
-
- # excluding PyPy as it chokes here on LXML
- if not IS_PYPY:
- ret = call_pytest_subprocess('interop/test_suds.py',
- capture=self.capture) or ret
- ret = call_pytest_subprocess('interop/test_zeep.py',
- capture=self.capture) or ret
-
- print("\nTest stage 3: Tox-managed tests")
- for djenv in djenvs:
- ret = call_tox_subprocess(djenv) or ret
-
- if ret == 0:
- print(GREEN + "All that glisters is not gold." + RESET)
- else:
- print(RED + "Something is rotten in the state of Denmark." + RESET)
-
- print ("Generating coverage.xml")
- call_coverage()
-
- raise SystemExit(ret)
-
-
-# Testing stuff ends here.
-###############################
-
-setup(
- name='spyne',
- packages=find_packages(),
-
- version=VERSION,
- description=SHORT_DESC,
- long_description=LONG_DESC,
- classifiers=[
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.6',
- 'Programming Language :: Python :: 3.7',
- 'Programming Language :: Python :: 3.8',
- 'Programming Language :: Python :: 3.9',
- 'Programming Language :: Python :: 3.10',
- 'Programming Language :: Python :: Implementation :: CPython',
- #'Programming Language :: Python :: Implementation :: Jython',
- 'Programming Language :: Python :: Implementation :: PyPy',
- 'Operating System :: OS Independent',
- 'Natural Language :: English',
- 'Development Status :: 5 - Production/Stable',
- 'Intended Audience :: Developers',
- 'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
- ],
- keywords='soap wsdl wsgi zeromq rest rpc json http msgpack xml'
- ' django pyramid postgresql sqlalchemy twisted yaml'.split(),
- author='Burak Arslan',
- author_email='burak+package@spyne.io',
- maintainer='Burak Arslan',
- maintainer_email='burak+package@spyne.io',
- url='http://spyne.io',
- license='LGPL-2.1-or-later',
- zip_safe=False,
- install_requires=[
- 'pytz',
- ],
-
- entry_points={
- 'console_scripts': [
- 'sort_wsdl=spyne.test.sort_wsdl:main',
- ]
- },
-
- cmdclass={
- 'test': RunTests,
- },
-)
diff --git a/spyne/__init__.py b/spyne/__init__.py
index f7e01853b..99fd1476b 100644
--- a/spyne/__init__.py
+++ b/spyne/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -21,66 +20,64 @@
class LogicError(Exception):
pass
-__version__ = '2.15.0-alpha'
-
-from pytz import utc as LOCAL_TZ
-from decimal import Decimal as D
-
-DEFAULT_LANGUAGE = 'en'
-
-from spyne._base import Address
-from spyne.context import AuxMethodContext
-from spyne.context import TransportContext
-from spyne.context import ProtocolContext
-from spyne.context import EventContext
-from spyne.context import MethodContext
+__version__ = "2.15.0-alpha"
-from spyne.evmgr import EventManager
-
-from spyne.descriptor import MethodDescriptor
-from spyne.descriptor import BODY_STYLE_WRAPPED
-from spyne.descriptor import BODY_STYLE_BARE
-from spyne.descriptor import BODY_STYLE_OUT_BARE
-from spyne.descriptor import BODY_STYLE_EMPTY
-from spyne.descriptor import BODY_STYLE_EMPTY_OUT_BARE
-
-# decorator imports descriptor, so this needs to come after
-from spyne.decorator import rpc
-from spyne.decorator import srpc
-from spyne.decorator import mrpc
+from decimal import Decimal as D
-from spyne.service import ServiceBase as Service
-from spyne.service import ServiceBase # DEPRECATED
+from pytz import utc as LOCAL_TZ
-from spyne.interface import Interface
-from spyne.interface import InterfaceDocuments
-from spyne.interface import InterfaceDocumentsBase
+DEFAULT_LANGUAGE = "en"
+from spyne._base import Address
from spyne.application import Application
+from spyne.client import ClientBase, RemoteProcedureBase, RemoteService
+from spyne.context import (
+ AuxMethodContext,
+ EventContext,
+ MethodContext,
+ ProtocolContext,
+ TransportContext,
+)
-from spyne.model import *
+# decorator imports descriptor, so this needs to come after
+from spyne.decorator import mrpc, rpc, srpc
+from spyne.descriptor import (
+ BODY_STYLE_BARE,
+ BODY_STYLE_EMPTY,
+ BODY_STYLE_EMPTY_OUT_BARE,
+ BODY_STYLE_OUT_BARE,
+ BODY_STYLE_WRAPPED,
+ MethodDescriptor,
+)
+from spyne.error import (
+ ArgumentError,
+ InternalError,
+ InvalidCredentialsError,
+ InvalidInputError,
+ MissingFieldError,
+ Redirect,
+ RequestNotAllowed,
+ RequestTooLongError,
+ ResourceAlreadyExistsError,
+ ResourceNotFoundError,
+ RespawnError,
+ ValidationError,
+)
+from spyne.evmgr import EventManager
+from spyne.interface import Interface, InterfaceDocuments, InterfaceDocumentsBase
from spyne.model import Mandatory as M
-
-from spyne.error import InvalidCredentialsError
-from spyne.error import RequestTooLongError
-from spyne.error import RequestNotAllowed
-from spyne.error import ArgumentError
-from spyne.error import InvalidInputError
-from spyne.error import MissingFieldError
-from spyne.error import ValidationError
-from spyne.error import InternalError
-from spyne.error import ResourceNotFoundError
-from spyne.error import RespawnError
-from spyne.error import ResourceAlreadyExistsError
-from spyne.error import Redirect
-
-from spyne.client import ClientBase, RemoteProcedureBase, RemoteService
-from spyne.server import ServerBase, NullServer
+from spyne.model import *
+from spyne.server import NullServer, ServerBase
+from spyne.service import ServiceBase # DEPRECATED
+from spyne.service import ServiceBase as Service
def _vercheck():
import sys
+
if not hasattr(sys, "version_info") or sys.version_info < (2, 6):
raise RuntimeError("Spyne requires Python 2.6 or later. Trust us.")
+
+
_vercheck()
diff --git a/spyne/_base.py b/spyne/_base.py
index 7f558fce3..bff2258d5 100644
--- a/spyne/_base.py
+++ b/spyne/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,7 +17,8 @@
#
import logging
-logger = logging.getLogger('spyne')
+
+logger = logging.getLogger("spyne")
from collections import namedtuple
@@ -27,11 +27,11 @@
Address = namedtuple("Address", ["type", "host", "port"])
-class _add_address_types():
- Address.TCP4 = 'TCP4'
- Address.TCP6 = 'TCP6'
- Address.UDP4 = 'UDP4'
- Address.UDP6 = 'UDP6'
+class _add_address_types:
+ Address.TCP4 = "TCP4"
+ Address.TCP6 = "TCP6"
+ Address.UDP4 = "UDP4"
+ Address.UDP6 = "UDP6"
def address_str(self):
return ":".join((self.type, self.host, str(self.port)))
@@ -42,6 +42,7 @@ def address_str(self):
@staticmethod
def _fta(*a, **kw):
from spyne.server.twisted._base import _address_from_twisted_address
+
return _address_from_twisted_address(*a, **kw)
Address.from_twisted_address = _fta
diff --git a/spyne/application.py b/spyne/application.py
index 5583f0b8a..f3316fa61 100644
--- a/spyne/application.py
+++ b/spyne/application.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,24 +17,23 @@
#
import logging
-logger = logging.getLogger(__name__)
-logger_client = logging.getLogger('.'.join([__name__, 'client']))
-logger_server = logging.getLogger('.'.join([__name__, 'server']))
-from pprint import pformat
+logger = logging.getLogger(__name__)
+logger_client = logging.getLogger(".".join([__name__, "client"]))
+logger_server = logging.getLogger(".".join([__name__, "server"]))
-from spyne import BODY_STYLE_EMPTY, BODY_STYLE_BARE, BODY_STYLE_WRAPPED, \
- EventManager
-from spyne.error import Fault, Redirect, RespawnError, InvalidRequestError
+from spyne.descriptor import BODY_STYLE_BARE, BODY_STYLE_EMPTY, BODY_STYLE_WRAPPED
+from spyne.error import Fault, InvalidRequestError, Redirect, RespawnError
+from spyne.evmgr import EventManager
from spyne.interface import Interface, InterfaceDocuments
-from spyne.util import six
from spyne.util.appreg import register_application
class MethodAlreadyExistsError(Exception):
def __init__(self, what):
- super(MethodAlreadyExistsError, self) \
- .__init__("Method key %r already exists", what)
+ super(MethodAlreadyExistsError, self).__init__(
+ "Method key %r already exists", what
+ )
def get_fault_string_from_exception(e):
@@ -51,8 +49,10 @@ def return_traceback_in_unhandled_exceptions():
global get_fault_string_from_exception
import traceback
+
def _get_fault_string_from_exception(e):
return traceback.format_exc()
+
get_fault_string_from_exception = _get_fault_string_from_exception
@@ -102,10 +102,17 @@ class Application(object):
transport = None
- def __init__(self, services, tns, name=None,
- in_protocol=None, out_protocol=None,
- config=None, classes=(),
- documents_container=InterfaceDocuments):
+ def __init__(
+ self,
+ services,
+ tns,
+ name=None,
+ in_protocol=None,
+ out_protocol=None,
+ config=None,
+ classes=(),
+ documents_container=InterfaceDocuments,
+ ):
self.services = tuple(services)
self.tns = tns
self.name = name
@@ -113,7 +120,7 @@ def __init__(self, services, tns, name=None,
self.classes = classes
if self.name is None:
- self.name = self.__class__.__name__.split('.')[-1]
+ self.name = self.__class__.__name__.split(".")[-1]
logger.info("Initializing application {%s}%s...", self.tns, self.name)
@@ -125,10 +132,12 @@ def __init__(self, services, tns, name=None,
if self.in_protocol is None:
from spyne.protocol import ProtocolBase
+
self.in_protocol = ProtocolBase()
if self.out_protocol is None:
from spyne.protocol import ProtocolBase
+
self.out_protocol = ProtocolBase()
self.check_unique_method_keys() # is this really necessary nowadays?
@@ -160,7 +169,7 @@ def process_request(self, ctx):
"""
try:
- ctx.fire_event('method_call')
+ ctx.fire_event("method_call")
# in object is always a sequence of incoming values. We need to fix
# that for bare mode.
@@ -174,8 +183,10 @@ def process_request(self, ctx):
# out object is always a sequence of return values. see
# MethodContext docstrings for more info
- if ctx.descriptor.body_style is not BODY_STYLE_WRAPPED or \
- len(ctx.descriptor.out_message._type_info) <= 1:
+ if (
+ ctx.descriptor.body_style is not BODY_STYLE_WRAPPED
+ or len(ctx.descriptor.out_message._type_info) <= 1
+ ):
# if it's not a wrapped method, OR there's just one return type
# we wrap it ourselves
ctx.out_object = [ctx.out_object]
@@ -184,7 +195,7 @@ def process_request(self, ctx):
# point ctx.protocol to ctx.out_protocol
ctx.protocol = ctx.outprot_ctx
- ctx.fire_event('method_return_object')
+ ctx.fire_event("method_return_object")
except Redirect as e:
try:
@@ -196,34 +207,33 @@ def process_request(self, ctx):
# point ctx.protocol to ctx.out_protocol
ctx.protocol = ctx.outprot_ctx
- ctx.fire_event('method_redirect')
+ ctx.fire_event("method_redirect")
except Exception as e:
logger_server.exception(e)
- ctx.out_error = Fault('Server',
- get_fault_string_from_exception(e))
+ ctx.out_error = Fault("Server", get_fault_string_from_exception(e))
- ctx.fire_event('method_redirect_exception')
+ ctx.fire_event("method_redirect_exception")
except Fault as e:
- if e.faultcode == 'Client' or e.faultcode.startswith('Client.'):
+ if e.faultcode == "Client" or e.faultcode.startswith("Client."):
logger_client.exception(e)
else:
logger.exception(e)
ctx.out_error = e
- ctx.fire_event('method_exception_object')
+ ctx.fire_event("method_exception_object")
# we don't catch BaseException because we actually don't want to catch
# "system-exiting" exceptions. See:
# https://docs.python.org/2/library/exceptions.html#exceptions.Exception
except Exception as e:
- logger_server.critical(e, **{'exc_info': 1})
+ logger_server.critical(e, **{"exc_info": 1})
- ctx.out_error = Fault('Server', get_fault_string_from_exception(e))
+ ctx.out_error = Fault("Server", get_fault_string_from_exception(e))
- ctx.fire_event('method_exception_object')
+ ctx.fire_event("method_exception_object")
def call_wrapper(self, ctx):
"""This method calls the call_wrapper method in the service definition.
@@ -249,8 +259,10 @@ def call_wrapper(self, ctx):
filters = {}
inst = cls.__respawn__(ctx, filters)
if inst is None:
- raise RespawnError('{%s}%s with params %r' %
- (cls.get_namespace(), cls.get_type_name(), filters))
+ raise RespawnError(
+ "{%s}%s with params %r"
+ % (cls.get_namespace(), cls.get_type_name(), filters)
+ )
in_cls = ctx.descriptor.in_message
@@ -258,8 +270,10 @@ def call_wrapper(self, ctx):
if args is None:
args = ()
- elif ctx.descriptor.body_style is BODY_STYLE_WRAPPED and \
- len(in_cls.get_flat_type_info(in_cls)) <= 1:
+ elif (
+ ctx.descriptor.body_style is BODY_STYLE_WRAPPED
+ and len(in_cls.get_flat_type_info(in_cls)) <= 1
+ ):
args = ()
else:
@@ -274,7 +288,10 @@ def call_wrapper(self, ctx):
if ctx.descriptor.no_ctx:
args = (inst,) + args
else:
- args = (inst, ctx,) + args
+ args = (
+ inst,
+ ctx,
+ ) + args
if ctx.descriptor.service_class is None:
retval = ctx.function(*args)
@@ -293,6 +310,7 @@ def reinitialize(self, server):
seen = set()
from spyne import MethodDescriptor
+
for d in self.interface.method_id_map.values():
assert isinstance(d, MethodDescriptor)
@@ -315,10 +333,11 @@ def check_unique_method_keys(self):
if other_mdesc is not None:
logger.error(
'Methods keys for "%s.%s" and "%s.%s" conflict',
- mdesc.function.__module__,
- six.get_function_name(mdesc.function),
- other_mdesc.function.__module__,
- six.get_function_name(other_mdesc.function))
+ mdesc.function.__module__,
+ mdesc.function.__name__,
+ other_mdesc.function.__module__,
+ other_mdesc.function.__name__,
+ )
raise MethodAlreadyExistsError(mdesc.internal_key)
keys[mdesc.internal_key] = mdesc
diff --git a/spyne/auxproc/__init__.py b/spyne/auxproc/__init__.py
index 19e90b3e0..a472f9848 100644
--- a/spyne/auxproc/__init__.py
+++ b/spyne/auxproc/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -38,5 +37,4 @@
This package is DEPRECATED. Get rid of this ASAP.
"""
-from spyne.auxproc._base import process_contexts
-from spyne.auxproc._base import AuxProcBase
+from spyne.auxproc._base import AuxProcBase, process_contexts
diff --git a/spyne/auxproc/_base.py b/spyne/auxproc/_base.py
index 565e6ef20..2ad9579c1 100644
--- a/spyne/auxproc/_base.py
+++ b/spyne/auxproc/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -24,6 +23,7 @@
"""
import logging
+
logger = logging.getLogger(__name__)
from spyne import AuxMethodContext
diff --git a/spyne/auxproc/sync.py b/spyne/auxproc/sync.py
index 4299fa70a..8d7c78e85 100644
--- a/spyne/auxproc/sync.py
+++ b/spyne/auxproc/sync.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,6 +17,7 @@
#
import logging
+
logger = logging.getLogger(__name__)
from spyne.auxproc import AuxProcBase
diff --git a/spyne/auxproc/thread.py b/spyne/auxproc/thread.py
index dd076e2da..b0823e017 100644
--- a/spyne/auxproc/thread.py
+++ b/spyne/auxproc/thread.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,6 +17,7 @@
#
import logging
+
logger = logging.getLogger(__name__)
from multiprocessing.pool import ThreadPool
diff --git a/spyne/client/__init__.py b/spyne/client/__init__.py
index 21025e981..8d2e4125e 100644
--- a/spyne/client/__init__.py
+++ b/spyne/client/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -19,7 +18,4 @@
"""The ``spyne.client`` package contains the client transports."""
-from spyne.client._base import Factory
-from spyne.client._base import RemoteService
-from spyne.client._base import ClientBase
-from spyne.client._base import RemoteProcedureBase
+from spyne.client._base import ClientBase, Factory, RemoteProcedureBase, RemoteService
diff --git a/spyne/client/_base.py b/spyne/client/_base.py
index a68c0b1a7..543ec68db 100644
--- a/spyne/client/_base.py
+++ b/spyne/client/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -41,8 +40,9 @@ def __init__(self, rpc_class, url, app, *args, **kwargs):
self.kwargs = kwargs
def __getattr__(self, key):
- return self.rpc_class(self.__url, self.__app, key, self.out_header,
- *self.args, **self.kwargs)
+ return self.rpc_class(
+ self.__url, self.__app, key, self.out_header, *self.args, **self.kwargs
+ )
class RemoteProcedureBase(object):
@@ -67,8 +67,7 @@ def __init__(self, url, app, name, out_header=None):
initial_ctx.method_request_string = name
initial_ctx.out_header = out_header
- self.contexts = initial_ctx.out_protocol.generate_method_contexts(
- initial_ctx)
+ self.contexts = initial_ctx.out_protocol.generate_method_contexts(initial_ctx)
def __call__(self, *args, **kwargs):
"""Serializes its arguments, sends them, receives and deserializes the
@@ -110,16 +109,16 @@ def get_out_string(self, ctx):
ctx.out_protocol.serialize(ctx, ctx.out_protocol.REQUEST)
if ctx.out_error is None:
- ctx.fire_event('method_return_document')
+ ctx.fire_event("method_return_document")
else:
- ctx.fire_event('method_exception_document')
+ ctx.fire_event("method_exception_document")
ctx.out_protocol.create_out_string(ctx, string_encoding)
if ctx.out_error is None:
- ctx.fire_event('method_return_string')
+ ctx.fire_event("method_return_string")
else:
- ctx.fire_event('method_exception_string')
+ ctx.fire_event("method_exception_string")
if ctx.out_string is None:
ctx.out_string = [""]
@@ -133,15 +132,15 @@ def get_in_object(self, ctx):
assert ctx.in_document is None
self.app.in_protocol.create_in_document(ctx)
- ctx.fire_event('method_accept_document')
+ ctx.fire_event("method_accept_document")
# sets the ctx.in_body_doc and ctx.in_header_doc properties
- self.app.in_protocol.decompose_incoming_envelope(ctx,
- message=self.app.in_protocol.RESPONSE)
+ self.app.in_protocol.decompose_incoming_envelope(
+ ctx, message=self.app.in_protocol.RESPONSE
+ )
# this sets ctx.in_object
- self.app.in_protocol.deserialize(ctx,
- message=self.app.in_protocol.RESPONSE)
+ self.app.in_protocol.deserialize(ctx, message=self.app.in_protocol.RESPONSE)
type_info = ctx.descriptor.out_message._type_info
@@ -167,10 +166,12 @@ def set_options(self, **kwargs):
:param soapheaders: A suds-compatible alias for out_header.
"""
- if ('soapheaders' in kwargs) and ('out_header' in kwargs):
- raise ValueError('you should specify only one of "soapheaders" or '
- '"out_header" keyword arguments.')
+ if ("soapheaders" in kwargs) and ("out_header" in kwargs):
+ raise ValueError(
+ 'you should specify only one of "soapheaders" or '
+ '"out_header" keyword arguments.'
+ )
- self.service.out_header = kwargs.get('soapheaders', None)
+ self.service.out_header = kwargs.get("soapheaders", None)
if self.service.out_header is None:
- self.service.out_header = kwargs.get('out_header', None)
+ self.service.out_header = kwargs.get("out_header", None)
diff --git a/spyne/client/django.py b/spyne/client/django.py
index 35e1eed59..52e39a154 100644
--- a/spyne/client/django.py
+++ b/spyne/client/django.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -21,19 +20,18 @@
"""The Django client transport for testing Spyne apps the way you'd test Django
apps."""
-
from __future__ import absolute_import
-from spyne import RemoteService, ClientBase, RemoteProcedureBase
-
from django.test.client import Client
+from spyne import ClientBase, RemoteProcedureBase, RemoteService
+
class _RemoteProcedure(RemoteProcedureBase):
def __init__(self, url, app, name, out_header=None, *args, **kwargs):
super(_RemoteProcedure, self).__init__(url, app, name, out_header=out_header)
- self.secure = kwargs.get('secure', False)
+ self.secure = kwargs.get("secure", False)
def __call__(self, *args, **kwargs):
response = self.get_django_response(*args, **kwargs)
@@ -58,7 +56,7 @@ def get_django_response(self, *args, **kwargs):
# the comma-in-assignment trick is a general way of getting the first
# and the only variable from an iterable. so if there's more than one
# element in the iterable, it'll fail miserably.
- self.ctx, = self.contexts
+ (self.ctx,) = self.contexts
# sets ctx.out_object
self.get_out_object(self.ctx, args, kwargs)
@@ -66,10 +64,12 @@ def get_django_response(self, *args, **kwargs):
# sets ctx.out_string
self.get_out_string(self.ctx)
- out_string = b''.join(self.ctx.out_string)
+ out_string = b"".join(self.ctx.out_string)
# Hack
client = Client()
- return client.post(self.url, content_type='text/xml', data=out_string, secure=self.secure)
+ return client.post(
+ self.url, content_type="text/xml", data=out_string, secure=self.secure
+ )
class DjangoTestClient(ClientBase):
diff --git a/spyne/client/http.py b/spyne/client/http.py
index 2101c3aa7..2bf789f38 100644
--- a/spyne/client/http.py
+++ b/spyne/client/http.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -19,10 +18,10 @@
"""The HTTP (urllib2) client transport."""
-from spyne import RemoteService, ClientBase, RemoteProcedureBase
+from urllib.error import HTTPError
+from urllib.request import Request, urlopen
-from spyne.util.six.moves.urllib.request import Request, urlopen
-from spyne.util.six.moves.urllib.error import HTTPError
+from spyne import ClientBase, RemoteProcedureBase, RemoteService
class _RemoteProcedure(RemoteProcedureBase):
@@ -32,7 +31,7 @@ def __call__(self, *args, **kwargs):
# the comma-in-assignment trick is a general way of getting the first
# and the only variable from an iterable. so if there's more than one
# element in the iterable, it'll fail miserably.
- self.ctx, = self.contexts
+ (self.ctx,) = self.contexts
# sets ctx.out_object
self.get_out_object(self.ctx, args, kwargs)
@@ -40,7 +39,9 @@ def __call__(self, *args, **kwargs):
# sets ctx.out_string
self.get_out_string(self.ctx)
- out_string = b''.join(self.ctx.out_string) # FIXME: just send the iterable to the http stream.
+ out_string = b"".join(
+ self.ctx.out_string
+ ) # FIXME: just send the iterable to the http stream.
request = Request(self.url, out_string)
code = 200
try:
diff --git a/spyne/client/twisted/__init__.py b/spyne/client/twisted/__init__.py
index 6609e82c8..141d09e5b 100644
--- a/spyne/client/twisted/__init__.py
+++ b/spyne/client/twisted/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -19,31 +18,19 @@
"""The Twisted Http Client transport."""
-from spyne import __version__ as VERSION
-from spyne.util import six
-
-from spyne.client import RemoteService
-from spyne.client import RemoteProcedureBase
-from spyne.client import ClientBase
-
-from zope.interface import implements
-
from twisted.internet import reactor
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Protocol
-
from twisted.web import error as werror
-from twisted.web.client import Agent
-from twisted.web.client import ResponseDone
-from twisted.web.iweb import IBodyProducer
-from twisted.web.iweb import UNKNOWN_LENGTH
+from twisted.web.client import Agent, ResponseDone
from twisted.web.http_headers import Headers
+from twisted.web.iweb import UNKNOWN_LENGTH, IBodyProducer
+
+from spyne import __version__ as VERSION
+from spyne.client import ClientBase, RemoteProcedureBase, RemoteService
class _Producer(object):
- if six.PY2:
- implements(IBodyProducer)
-
_deferred = None
def __init__(self, body):
@@ -53,7 +40,7 @@ def __init__(self, body):
# check to see if we can determine the length
try:
- len(body) # iterator?
+ len(body) # iterator?
self.length = sum([len(fragment) for fragment in body])
self.body = iter(body)
@@ -76,7 +63,7 @@ def resumeProducing(self):
if self.__paused:
break
else:
- self._deferred.callback(None) # done producing forever
+ self._deferred.callback(None) # done producing forever
def pauseProducing(self):
self.__paused = True
@@ -107,7 +94,7 @@ def __call__(self, *args, **kwargs):
# The comma-in-assignment trick is a pedantic way of getting the first
# and the only variable from an iterable. so if there's more than one
# element in the iterable, it'll fail miserably.
- self.ctx, = self.contexts
+ (self.ctx,) = self.contexts
self.get_out_object(self.ctx, args, kwargs)
self.get_out_string(self.ctx)
@@ -116,10 +103,12 @@ def __call__(self, *args, **kwargs):
agent = Agent(reactor)
d = agent.request(
- b'POST', self.url,
- Headers({b'User-Agent':
- [b'Spyne Twisted Http Client %s' % VERSION.encode()]}),
- _Producer(self.ctx.out_string)
+ b"POST",
+ self.url,
+ Headers(
+ {b"User-Agent": [b"Spyne Twisted Http Client %s" % VERSION.encode()]}
+ ),
+ _Producer(self.ctx.out_string),
)
def _process_response(_, response):
diff --git a/spyne/client/zeromq.py b/spyne/client/zeromq.py
index 70c97968a..6b855939b 100644
--- a/spyne/client/zeromq.py
+++ b/spyne/client/zeromq.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -21,7 +20,7 @@
import zmq
-from spyne import RemoteService, ClientBase, RemoteProcedureBase
+from spyne import ClientBase, RemoteProcedureBase, RemoteService
context = zmq.Context()
@@ -32,7 +31,7 @@ def __call__(self, *args, **kwargs):
self.get_out_object(self.ctx, args, kwargs)
self.get_out_string(self.ctx)
- out_string = b''.join(self.ctx.out_string)
+ out_string = b"".join(self.ctx.out_string)
socket = context.socket(zmq.REQ)
socket.connect(self.url)
diff --git a/spyne/const/__init__.py b/spyne/const/__init__.py
index eb5ca9043..583efd3ac 100644
--- a/spyne/const/__init__.py
+++ b/spyne/const/__init__.py
@@ -1,5 +1,3 @@
-
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -21,7 +19,6 @@
"""The ``spyne.const`` package contains miscellanous constant values needed
in various parts of Spyne."""
-
MAX_STRING_FIELD_LENGTH = 64
"""Maximum length of a string field for :func:`spyne.util.log_repr`"""
@@ -34,41 +31,41 @@
MAX_FIELD_NUM = 10
"""Maximum number of complex model fields for :func:`spyne.util.log_repr`"""
-ARRAY_PREFIX = ''
+ARRAY_PREFIX = ""
"""The prefix for Array wrapper objects. You may want to set this to 'ArrayOf'
and the ARRAY_SUFFIX to '' for compatibility with some SOAP deployments."""
-ARRAY_SUFFIX = 'Array'
+ARRAY_SUFFIX = "Array"
"""The suffix for Array wrapper objects."""
-REQUEST_SUFFIX = ''
+REQUEST_SUFFIX = ""
"""The suffix for function response objects."""
-RESPONSE_SUFFIX = 'Response'
+RESPONSE_SUFFIX = "Response"
"""The suffix for function response objects."""
-RESULT_SUFFIX = 'Result'
+RESULT_SUFFIX = "Result"
"""The suffix for function response wrapper objects."""
-TYPE_SUFFIX = 'Type'
+TYPE_SUFFIX = "Type"
"""The suffix for primitives with unnamed constraints."""
-PARENT_SUFFIX = 'Parent'
+PARENT_SUFFIX = "Parent"
"""The suffix for parent classes of primitives with unnamed constraints."""
-MANDATORY_PREFIX = 'Mandatory'
+MANDATORY_PREFIX = "Mandatory"
"""The prefix for types created with the :func:`spyne.model.Mandatory`."""
-MANDATORY_SUFFIX = ''
+MANDATORY_SUFFIX = ""
"""The suffix for types created with the :func:`spyne.model.Mandatory`."""
-DEFAULT_DECLARE_ORDER = 'random'
+DEFAULT_DECLARE_ORDER = "random"
"""Order of complex type attrs of :class:`spyne.model.complex.ComplexModel`."""
MIN_GC_INTERVAL = 1.0
"""Minimum time in seconds between gc.collect() calls."""
-DEFAULT_LOCALE = 'en_US'
+DEFAULT_LOCALE = "en_US"
"""Locale code to use for the translation subsystem when locale information is
missing in an incoming request."""
diff --git a/spyne/const/ansi_color.py b/spyne/const/ansi_color.py
index 98935ba25..02452bc4d 100644
--- a/spyne/const/ansi_color.py
+++ b/spyne/const/ansi_color.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -41,6 +40,7 @@
"""ANSI colour value for end color marker if colours are enabled, empty string
otherwise."""
+
def enable_color():
"""Enable colors by setting colour code constants to ANSI color codes."""
@@ -78,4 +78,5 @@ def disable_color():
global END_COLOR
END_COLOR = ""
+
enable_color()
diff --git a/spyne/const/http.py b/spyne/const/http.py
index e6a002520..25d13d843 100644
--- a/spyne/const/http.py
+++ b/spyne/const/http.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -19,98 +18,103 @@
"""The ``spyne.const.http module contains the Http response status codes."""
-HTTP_200 = '200 OK'
-HTTP_201 = '201 Created'
-HTTP_202 = '202 Accepted'
-HTTP_203 = '203 Non-Authoritative Information' # (since HTTP/1.1)
-HTTP_204 = '204 No Content'
-HTTP_205 = '205 Reset Content'
-HTTP_206 = '206 Partial Content'
-HTTP_207 = '207 Multi-Status' # (WebDAV; RFC 4918)
-HTTP_208 = '208 Already Reported' # (WebDAV; RFC 5842)
-HTTP_226 = '226 IM Used' # (RFC 3229)
+HTTP_200 = "200 OK"
+HTTP_201 = "201 Created"
+HTTP_202 = "202 Accepted"
+HTTP_203 = "203 Non-Authoritative Information" # (since HTTP/1.1)
+HTTP_204 = "204 No Content"
+HTTP_205 = "205 Reset Content"
+HTTP_206 = "206 Partial Content"
+HTTP_207 = "207 Multi-Status" # (WebDAV; RFC 4918)
+HTTP_208 = "208 Already Reported" # (WebDAV; RFC 5842)
+HTTP_226 = "226 IM Used" # (RFC 3229)
-HTTP_300 = '300 Multiple Choices'
-HTTP_301 = '301 Moved Permanently'
-HTTP_302 = '302 Found'
-HTTP_303 = '303 See Other' # (since HTTP/1.1)
-HTTP_304 = '304 Not Modified'
-HTTP_305 = '305 Use Proxy' # (since HTTP/1.1)
-HTTP_306 = '306 Switch Proxy'
-HTTP_307 = '307 Temporary Redirect' # (since HTTP/1.1)
-HTTP_308 = '308 Permanent Redirect' # (approved as experimental RFC])[11]
+HTTP_300 = "300 Multiple Choices"
+HTTP_301 = "301 Moved Permanently"
+HTTP_302 = "302 Found"
+HTTP_303 = "303 See Other" # (since HTTP/1.1)
+HTTP_304 = "304 Not Modified"
+HTTP_305 = "305 Use Proxy" # (since HTTP/1.1)
+HTTP_306 = "306 Switch Proxy"
+HTTP_307 = "307 Temporary Redirect" # (since HTTP/1.1)
+HTTP_308 = "308 Permanent Redirect" # (approved as experimental RFC])[11]
-HTTP_400 = '400 Bad Request'
-HTTP_401 = '401 Unauthorized'
-HTTP_402 = '402 Payment Required'
-HTTP_403 = '403 Forbidden'
-HTTP_404 = '404 Not Found'
-HTTP_405 = '405 Method Not Allowed'
-HTTP_406 = '406 Not Acceptable'
-HTTP_407 = '407 Proxy Authentication Required'
-HTTP_408 = '408 Request Timeout'
-HTTP_409 = '409 Conflict'
-HTTP_410 = '410 Gone'
-HTTP_411 = '411 Length Required'
-HTTP_412 = '412 Precondition Failed'
-HTTP_413 = '413 Request Entity Too Large'
-HTTP_414 = '414 Request-URI Too Long'
-HTTP_415 = '415 Unsupported Media Type'
-HTTP_416 = '416 Requested Range Not Satisfiable'
-HTTP_417 = '417 Expectation Failed'
-HTTP_418 = "418 I'm a teapot" # (RFC 2324)
+HTTP_400 = "400 Bad Request"
+HTTP_401 = "401 Unauthorized"
+HTTP_402 = "402 Payment Required"
+HTTP_403 = "403 Forbidden"
+HTTP_404 = "404 Not Found"
+HTTP_405 = "405 Method Not Allowed"
+HTTP_406 = "406 Not Acceptable"
+HTTP_407 = "407 Proxy Authentication Required"
+HTTP_408 = "408 Request Timeout"
+HTTP_409 = "409 Conflict"
+HTTP_410 = "410 Gone"
+HTTP_411 = "411 Length Required"
+HTTP_412 = "412 Precondition Failed"
+HTTP_413 = "413 Request Entity Too Large"
+HTTP_414 = "414 Request-URI Too Long"
+HTTP_415 = "415 Unsupported Media Type"
+HTTP_416 = "416 Requested Range Not Satisfiable"
+HTTP_417 = "417 Expectation Failed"
+HTTP_418 = "418 I'm a teapot" # (RFC 2324)
-HTTP_420 = '420 Enhance Your Calm' # (Twitter)
-HTTP_422 = '422 Unprocessable Entity' # (WebDAV; RFC 4918)
-HTTP_423 = '423 Locked' # (WebDAV; RFC 4918)
-HTTP_424 = '424 Failed Dependency' # (WebDAV; RFC 4918)
+HTTP_420 = "420 Enhance Your Calm" # (Twitter)
+HTTP_422 = "422 Unprocessable Entity" # (WebDAV; RFC 4918)
+HTTP_423 = "423 Locked" # (WebDAV; RFC 4918)
+HTTP_424 = "424 Failed Dependency" # (WebDAV; RFC 4918)
-HTTP_425 = '425 Unordered Collection' # (Internet draft)
-HTTP_426 = '426 Upgrade Required' # (RFC 2817)
-HTTP_428 = '428 Precondition Required' # (RFC 6585)
-HTTP_429 = '429 Too Many Requests' # (RFC 6585)
-HTTP_431 = '431 Request Header Fields Too Large' # (RFC 6585)
-HTTP_444 = '444 No Response' # (Nginx)
-HTTP_449 = '449 Retry With' # (Microsoft)
-HTTP_450 = '450 Blocked by Windows Parental Controls' # (Microsoft)
-HTTP_451 = '451 Unavailable For Legal Reasons' # (Internet draft)
-HTTP_494 = '494 Request Header Too Large' # (Nginx)
-HTTP_495 = '495 Cert Error' # (Nginx)
-HTTP_496 = '496 No Cert' # (Nginx)
-HTTP_497 = '497 HTTP to HTTPS' # (Nginx)
-HTTP_499 = '499 Client Closed Request' # (Nginx)
+HTTP_425 = "425 Unordered Collection" # (Internet draft)
+HTTP_426 = "426 Upgrade Required" # (RFC 2817)
+HTTP_428 = "428 Precondition Required" # (RFC 6585)
+HTTP_429 = "429 Too Many Requests" # (RFC 6585)
+HTTP_431 = "431 Request Header Fields Too Large" # (RFC 6585)
+HTTP_444 = "444 No Response" # (Nginx)
+HTTP_449 = "449 Retry With" # (Microsoft)
+HTTP_450 = "450 Blocked by Windows Parental Controls" # (Microsoft)
+HTTP_451 = "451 Unavailable For Legal Reasons" # (Internet draft)
+HTTP_494 = "494 Request Header Too Large" # (Nginx)
+HTTP_495 = "495 Cert Error" # (Nginx)
+HTTP_496 = "496 No Cert" # (Nginx)
+HTTP_497 = "497 HTTP to HTTPS" # (Nginx)
+HTTP_499 = "499 Client Closed Request" # (Nginx)
-HTTP_500 = '500 Internal Server Error'
-HTTP_501 = '501 Not Implemented'
-HTTP_502 = '502 Bad Gateway'
-HTTP_503 = '503 Service Unavailable'
-HTTP_504 = '504 Gateway Timeout'
-HTTP_505 = '505 HTTP Version Not Supported'
-HTTP_506 = '506 Variant Also Negotiates' # (RFC 2295)
-HTTP_507 = '507 Insufficient Storage' # (WebDAV; RFC 4918)
-HTTP_508 = '508 Loop Detected' # (WebDAV; RFC 5842)
-HTTP_509 = '509 Bandwidth Limit Exceeded' # (Apache bw/limited extension)
-HTTP_510 = '510 Not Extended' # (RFC 2774)
-HTTP_511 = '511 Network Authentication Required' # (RFC 6585)
-HTTP_598 = '598 Network read timeout error' # (Unknown)
-HTTP_599 = '599 Network connect timeout error' # (Unknown)
+HTTP_500 = "500 Internal Server Error"
+HTTP_501 = "501 Not Implemented"
+HTTP_502 = "502 Bad Gateway"
+HTTP_503 = "503 Service Unavailable"
+HTTP_504 = "504 Gateway Timeout"
+HTTP_505 = "505 HTTP Version Not Supported"
+HTTP_506 = "506 Variant Also Negotiates" # (RFC 2295)
+HTTP_507 = "507 Insufficient Storage" # (WebDAV; RFC 4918)
+HTTP_508 = "508 Loop Detected" # (WebDAV; RFC 5842)
+HTTP_509 = "509 Bandwidth Limit Exceeded" # (Apache bw/limited extension)
+HTTP_510 = "510 Not Extended" # (RFC 2774)
+HTTP_511 = "511 Network Authentication Required" # (RFC 6585)
+HTTP_598 = "598 Network read timeout error" # (Unknown)
+HTTP_599 = "599 Network connect timeout error" # (Unknown)
def gen_body_redirect(code, location):
- from lxml.html.builder import E
from lxml.html import tostring
- return tostring(E.HTML(
- E.HEAD(
- E.meta(**{
- "http-equiv": "content-type",
- "content": "text/html;charset=utf-8",
- }),
- E.TITLE(code),
- ),
- E.BODY(
- E.H1(code),
- E.P("The document has moved"),
- E.A("here", HREF=location),
- ".",
+ from lxml.html.builder import E
+
+ return tostring(
+ E.HTML(
+ E.HEAD(
+ E.meta(
+ **{
+ "http-equiv": "content-type",
+ "content": "text/html;charset=utf-8",
+ }
+ ),
+ E.TITLE(code),
+ ),
+ E.BODY(
+ E.H1(code),
+ E.P("The document has moved"),
+ E.A("here", HREF=location),
+ ".",
+ ),
)
- ))
+ )
diff --git a/spyne/const/xml.py b/spyne/const/xml.py
index e320e0b06..76a71c2b9 100644
--- a/spyne/const/xml.py
+++ b/spyne/const/xml.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -21,59 +20,64 @@
namespace prefixes, namespace values and schema uris.
"""
-NS_XML = 'http://www.w3.org/XML/1998/namespace'
-NS_XSD = 'http://www.w3.org/2001/XMLSchema'
-NS_XSI = 'http://www.w3.org/2001/XMLSchema-instance'
-NS_WSA = 'http://schemas.xmlsoap.org/ws/2003/03/addressing'
-NS_XOP = 'http://www.w3.org/2004/08/xop/include'
-NS_XHTML = 'http://www.w3.org/1999/xhtml'
-NS_PLINK = 'http://schemas.xmlsoap.org/ws/2003/05/partner-link/'
-NS_SOAP11_ENC = 'http://schemas.xmlsoap.org/soap/encoding/'
-NS_SOAP11_ENV = 'http://schemas.xmlsoap.org/soap/envelope/'
-NS_SOAP12_ENC = 'http://www.w3.org/2003/05/soap-encoding'
-NS_SOAP12_ENV = 'http://www.w3.org/2003/05/soap-envelope'
-
-NS_WSDL11 = 'http://schemas.xmlsoap.org/wsdl/'
-NS_WSDL11_SOAP = 'http://schemas.xmlsoap.org/wsdl/soap/'
-NS_WSDL11_SOAP12 = 'http://schemas.xmlsoap.org/wsdl/soap12/'
-NS_WSDL11_HTTP = 'http://schemas.xmlsoap.org/wsdl/http/'
+NS_XML = "http://www.w3.org/XML/1998/namespace"
+NS_XSD = "http://www.w3.org/2001/XMLSchema"
+NS_XSI = "http://www.w3.org/2001/XMLSchema-instance"
+NS_WSA = "http://schemas.xmlsoap.org/ws/2003/03/addressing"
+NS_XOP = "http://www.w3.org/2004/08/xop/include"
+NS_XHTML = "http://www.w3.org/1999/xhtml"
+NS_PLINK = "http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
+NS_SOAP11_ENC = "http://schemas.xmlsoap.org/soap/encoding/"
+NS_SOAP11_ENV = "http://schemas.xmlsoap.org/soap/envelope/"
+NS_SOAP12_ENC = "http://www.w3.org/2003/05/soap-encoding"
+NS_SOAP12_ENV = "http://www.w3.org/2003/05/soap-envelope"
+
+NS_WSDL11 = "http://schemas.xmlsoap.org/wsdl/"
+NS_WSDL11_SOAP = "http://schemas.xmlsoap.org/wsdl/soap/"
+NS_WSDL11_SOAP12 = "http://schemas.xmlsoap.org/wsdl/soap12/"
+NS_WSDL11_HTTP = "http://schemas.xmlsoap.org/wsdl/http/"
NSMAP = {
- 'xml': NS_XML,
- 'xs': NS_XSD,
- 'xsi': NS_XSI,
- 'plink': NS_PLINK,
- 'wsdlsoap11': NS_WSDL11_SOAP,
- 'wsdlsoap12': NS_WSDL11_SOAP12,
- 'wsdl': NS_WSDL11,
- 'soap11enc': NS_SOAP11_ENC,
- 'soap11env': NS_SOAP11_ENV,
- 'soap12env': NS_SOAP12_ENV,
- 'soap12enc': NS_SOAP12_ENC,
- 'wsa': NS_WSA,
- 'xop': NS_XOP,
- 'http': NS_WSDL11_HTTP,
+ "xml": NS_XML,
+ "xs": NS_XSD,
+ "xsi": NS_XSI,
+ "plink": NS_PLINK,
+ "wsdlsoap11": NS_WSDL11_SOAP,
+ "wsdlsoap12": NS_WSDL11_SOAP12,
+ "wsdl": NS_WSDL11,
+ "soap11enc": NS_SOAP11_ENC,
+ "soap11env": NS_SOAP11_ENV,
+ "soap12env": NS_SOAP12_ENV,
+ "soap12enc": NS_SOAP12_ENC,
+ "wsa": NS_WSA,
+ "xop": NS_XOP,
+ "http": NS_WSDL11_HTTP,
}
PREFMAP = None
+
+
def _regen_prefmap():
global PREFMAP
PREFMAP = dict([(b, a) for a, b in NSMAP.items()])
+
+
_regen_prefmap()
schema_location = {
- NS_XSD: 'http://www.w3.org/2001/XMLSchema.xsd',
+ NS_XSD: "http://www.w3.org/2001/XMLSchema.xsd",
}
-class DEFAULT_NS(object): pass
+class DEFAULT_NS(object):
+ pass
def get_binding_ns(protocol_type):
"Returns the wsdl binding namespace based on the protocol type"
- if 'soap12' in protocol_type:
+ if "soap12" in protocol_type:
return WSDL11_SOAP12
- elif 'http' in protocol_type:
+ elif "http" in protocol_type:
return WSDL11_HTTP
else:
# Bind to Soap1.1 namespace by default for backwards compatibility
@@ -101,87 +105,94 @@ def Tnswrap(ns):
WSDL11_HTTP = Tnswrap(NS_WSDL11_HTTP)
# names starting with underscore need () around to be used as proper regexps
-_PATT_BASE_CHAR = \
- u"[\u0041-\u005A]|[\u0061-\u007A]|[\u00C0-\u00D6]|[\u00D8-\u00F6]" \
- u"|[\u00F8-\u00FF]|[\u0100-\u0131]|[\u0134-\u013E]|[\u0141-\u0148]" \
- u"|[\u014A-\u017E]|[\u0180-\u01C3]|[\u01CD-\u01F0]|[\u01F4-\u01F5]" \
- u"|[\u01FA-\u0217]|[\u0250-\u02A8]|[\u02BB-\u02C1]|\u0386|[\u0388-\u038A]" \
- u"|\u038C|[\u038E-\u03A1]|[\u03A3-\u03CE]|[\u03D0-\u03D6]" \
- u"|\u03DA|\u03DC|\u03DE|\u03E0|[\u03E2-\u03F3]|[\u0401-\u040C]" \
- u"|[\u040E-\u044F]|[\u0451-\u045C]|[\u045E-\u0481]|[\u0490-\u04C4]" \
- u"|[\u04C7-\u04C8]|[\u04CB-\u04CC]|[\u04D0-\u04EB]|[\u04EE-\u04F5]" \
- u"|[\u04F8-\u04F9]|[\u0531-\u0556]|\u0559|[\u0561-\u0586]|[\u05D0-\u05EA]" \
- u"|[\u05F0-\u05F2]|[\u0621-\u063A]|[\u0641-\u064A]|[\u0671-\u06B7]" \
- u"|[\u06BA-\u06BE]|[\u06C0-\u06CE]|[\u06D0-\u06D3]|\u06D5|[\u06E5-\u06E6]" \
- u"|[\u0905-\u0939]|\u093D|[\u0958-\u0961]|[\u0985-\u098C]|[\u098F-\u0990]" \
- u"|[\u0993-\u09A8]|[\u09AA-\u09B0]|\u09B2|[\u09B6-\u09B9]|[\u09DC-\u09DD]" \
- u"|[\u09DF-\u09E1]|[\u09F0-\u09F1]|[\u0A05-\u0A0A]|[\u0A0F-\u0A10]" \
- u"|[\u0A13-\u0A28]|[\u0A2A-\u0A30]|[\u0A32-\u0A33]|[\u0A35-\u0A36]" \
- u"|[\u0A38-\u0A39]|[\u0A59-\u0A5C]|\u0A5E|[\u0A72-\u0A74]|[\u0A85-\u0A8B]" \
- u"|\u0A8D|[\u0A8F-\u0A91]|[\u0A93-\u0AA8]|[\u0AAA-\u0AB0]|[\u0AB2-\u0AB3]" \
- u"|[\u0AB5-\u0AB9]|\u0ABD|\u0AE0|[\u0B05-\u0B0C]|[\u0B0F-\u0B10]" \
- u"|[\u0B13-\u0B28]|[\u0B2A-\u0B30]|[\u0B32-\u0B33]|[\u0B36-\u0B39]|\u0B3D" \
- u"|[\u0B5C-\u0B5D]|[\u0B5F-\u0B61]|[\u0B85-\u0B8A]|[\u0B8E-\u0B90]" \
- u"|[\u0B92-\u0B95]|[\u0B99-\u0B9A]|\u0B9C|[\u0B9E-\u0B9F]|[\u0BA3-\u0BA4]" \
- u"|[\u0BA8-\u0BAA]|[\u0BAE-\u0BB5]|[\u0BB7-\u0BB9]|[\u0C05-\u0C0C]" \
- u"|[\u0C0E-\u0C10]|[\u0C12-\u0C28]|[\u0C2A-\u0C33]|[\u0C35-\u0C39]" \
- u"|[\u0C60-\u0C61]|[\u0C85-\u0C8C]|[\u0C8E-\u0C90]|[\u0C92-\u0CA8]" \
- u"|[\u0CAA-\u0CB3]|[\u0CB5-\u0CB9]|\u0CDE|[\u0CE0-\u0CE1]|[\u0D05-\u0D0C]" \
- u"|[\u0D0E-\u0D10]|[\u0D12-\u0D28]|[\u0D2A-\u0D39]|[\u0D60-\u0D61]" \
- u"|[\u0E01-\u0E2E]|\u0E30|[\u0E32-\u0E33]|[\u0E40-\u0E45]|[\u0E81-\u0E82]" \
- u"|\u0E84|[\u0E87-\u0E88]|\u0E8A|\u0E8D|[\u0E94-\u0E97]|[\u0E99-\u0E9F]" \
- u"|[\u0EA1-\u0EA3]|\u0EA5|\u0EA7|[\u0EAA-\u0EAB]|[\u0EAD-\u0EAE]|\u0EB0" \
- u"|[\u0EB2-\u0EB3]|\u0EBD|[\u0EC0-\u0EC4]|[\u0F40-\u0F47]|[\u0F49-\u0F69]" \
- u"|[\u10A0-\u10C5]|[\u10D0-\u10F6]|\u1100|[\u1102-\u1103]|[\u1105-\u1107]" \
- u"|\u1109|[\u110B-\u110C]|[\u110E-\u1112]|\u113C|\u113E|\u1140|\u114C" \
- u"|\u114E|\u1150|[\u1154-\u1155]|\u1159|[\u115F-\u1161]|\u1163|\u1165" \
- u"|\u1167|\u1169|[\u116D-\u116E]|[\u1172-\u1173]|\u1175|\u119E|\u11A8" \
- u"|\u11AB|[\u11AE-\u11AF]|[\u11B7-\u11B8]|\u11BA|[\u11BC-\u11C2]|\u11EB" \
- u"|\u11F0|\u11F9|[\u1E00-\u1E9B]|[\u1EA0-\u1EF9]|[\u1F00-\u1F15]" \
- u"|[\u1F18-\u1F1D]|[\u1F20-\u1F45]|[\u1F48-\u1F4D]|[\u1F50-\u1F57]|\u1F59" \
- u"|\u1F5B|\u1F5D|[\u1F5F-\u1F7D]|[\u1F80-\u1FB4]|[\u1FB6-\u1FBC]|\u1FBE" \
- u"|[\u1FC2-\u1FC4]|[\u1FC6-\u1FCC]|[\u1FD0-\u1FD3]|[\u1FD6-\u1FDB]" \
- u"|[\u1FE0-\u1FEC]|[\u1FF2-\u1FF4]|[\u1FF6-\u1FFC]|\u2126|[\u212A-\u212B]" \
- u"|\u212E|[\u2180-\u2182]|[\u3041-\u3094]|[\u30A1-\u30FA]|[\u3105-\u312C]" \
- u"|[\uAC00-\uD7A3]"
-
-_PATT_IDEOGRAPHIC = u"[\u4E00-\u9FA5]|\u3007|[\u3021-\u3029]"
-
-_PATT_COMBINING_CHAR = u"[\u0300-\u0345]|[\u0360-\u0361]|[\u0483-\u0486]" \
- u"|[\u0591-\u05A1]|[\u05A3-\u05B9]|[\u05BB-\u05BD]|\u05BF|[\u05C1-\u05C2]" \
- u"|\u05C4|[\u064B-\u0652]|\u0670|[\u06D6-\u06DC]|[\u06DD-\u06DF]" \
- u"|[\u06E0-\u06E4]|[\u06E7-\u06E8]|[\u06EA-\u06ED]|[\u0901-\u0903]|\u093C" \
- u"|[\u093E-\u094C]|\u094D|[\u0951-\u0954]|[\u0962-\u0963]|[\u0981-\u0983]" \
- u"|\u09BC|\u09BE|\u09BF|[\u09C0-\u09C4]|[\u09C7-\u09C8]|[\u09CB-\u09CD]" \
- u"|\u09D7|[\u09E2-\u09E3]|\u0A02|\u0A3C|\u0A3E|\u0A3F|[\u0A40-\u0A42]" \
- u"|[\u0A47-\u0A48]|[\u0A4B-\u0A4D]|[\u0A70-\u0A71]|[\u0A81-\u0A83]|\u0ABC" \
- u"|[\u0ABE-\u0AC5]|[\u0AC7-\u0AC9]|[\u0ACB-\u0ACD]|[\u0B01-\u0B03]|\u0B3C" \
- u"|[\u0B3E-\u0B43]|[\u0B47-\u0B48]|[\u0B4B-\u0B4D]|[\u0B56-\u0B57]" \
- u"|[\u0B82-\u0B83]|[\u0BBE-\u0BC2]|[\u0BC6-\u0BC8]|[\u0BCA-\u0BCD]|\u0BD7" \
- u"|[\u0C01-\u0C03]|[\u0C3E-\u0C44]|[\u0C46-\u0C48]|[\u0C4A-\u0C4D]" \
- u"|[\u0C55-\u0C56]|[\u0C82-\u0C83]|[\u0CBE-\u0CC4]|[\u0CC6-\u0CC8]" \
- u"|[\u0CCA-\u0CCD]|[\u0CD5-\u0CD6]|[\u0D02-\u0D03]|[\u0D3E-\u0D43]" \
- u"|[\u0D46-\u0D48]|[\u0D4A-\u0D4D]|\u0D57|\u0E31|[\u0E34-\u0E3A]" \
- u"|[\u0E47-\u0E4E]|\u0EB1|[\u0EB4-\u0EB9]|[\u0EBB-\u0EBC]|[\u0EC8-\u0ECD]" \
- u"|[\u0F18-\u0F19]|\u0F35|\u0F37|\u0F39|\u0F3E|\u0F3F|[\u0F71-\u0F84]" \
- u"|[\u0F86-\u0F8B]|[\u0F90-\u0F95]|\u0F97|[\u0F99-\u0FAD]|[\u0FB1-\u0FB7]" \
- u"|\u0FB9|[\u20D0-\u20DC]|\u20E1|[\u302A-\u302F]|\u3099|\u309A"
-
-_PATT_DIGIT = u"[\u0030-\u0039]|[\u0660-\u0669]|[\u06F0-\u06F9]|[\u0966-\u096F]" \
- u"|[\u09E6-\u09EF]|[\u0A66-\u0A6F]|[\u0AE6-\u0AEF]|[\u0B66-\u0B6F]" \
- u"|[\u0BE7-\u0BEF]|[\u0C66-\u0C6F]|[\u0CE6-\u0CEF]|[\u0D66-\u0D6F]" \
- u"|[\u0E50-\u0E59]|[\u0ED0-\u0ED9]|[\u0F20-\u0F29]"
-
-_PATT_EXTENDER = u"\u00B7|\u02D0|\u02D1|\u0387|\u0640|\u0E46|\u0EC6|\u3005" \
- u"|[\u3031-\u3035]|[\u309D-\u309E]|[\u30FC-\u30FE]"
-
-
-PATT_LETTER = u"(%s)" % u'|'.join([_PATT_BASE_CHAR, _PATT_IDEOGRAPHIC])
-
-PATT_NAMECHAR = u"(%s)" % u'|'.join([PATT_LETTER, _PATT_DIGIT,
- u'.', u'-', u'_', u':', _PATT_COMBINING_CHAR, _PATT_EXTENDER])
-
-PATT_NAME = u"(%s)(%s)+" % (u'|'.join([PATT_LETTER, u'_', u':']),
- u"(%s)*" % PATT_NAMECHAR)
-
-PATT_NMTOKEN = u"(%s)+" % PATT_NAMECHAR
+_PATT_BASE_CHAR = (
+ "[\u0041-\u005a]|[\u0061-\u007a]|[\u00c0-\u00d6]|[\u00d8-\u00f6]"
+ "|[\u00f8-\u00ff]|[\u0100-\u0131]|[\u0134-\u013e]|[\u0141-\u0148]"
+ "|[\u014a-\u017e]|[\u0180-\u01c3]|[\u01cd-\u01f0]|[\u01f4-\u01f5]"
+ "|[\u01fa-\u0217]|[\u0250-\u02a8]|[\u02bb-\u02c1]|\u0386|[\u0388-\u038a]"
+ "|\u038c|[\u038e-\u03a1]|[\u03a3-\u03ce]|[\u03d0-\u03d6]"
+ "|\u03da|\u03dc|\u03de|\u03e0|[\u03e2-\u03f3]|[\u0401-\u040c]"
+ "|[\u040e-\u044f]|[\u0451-\u045c]|[\u045e-\u0481]|[\u0490-\u04c4]"
+ "|[\u04c7-\u04c8]|[\u04cb-\u04cc]|[\u04d0-\u04eb]|[\u04ee-\u04f5]"
+ "|[\u04f8-\u04f9]|[\u0531-\u0556]|\u0559|[\u0561-\u0586]|[\u05d0-\u05ea]"
+ "|[\u05f0-\u05f2]|[\u0621-\u063a]|[\u0641-\u064a]|[\u0671-\u06b7]"
+ "|[\u06ba-\u06be]|[\u06c0-\u06ce]|[\u06d0-\u06d3]|\u06d5|[\u06e5-\u06e6]"
+ "|[\u0905-\u0939]|\u093d|[\u0958-\u0961]|[\u0985-\u098c]|[\u098f-\u0990]"
+ "|[\u0993-\u09a8]|[\u09aa-\u09b0]|\u09b2|[\u09b6-\u09b9]|[\u09dc-\u09dd]"
+ "|[\u09df-\u09e1]|[\u09f0-\u09f1]|[\u0a05-\u0a0a]|[\u0a0f-\u0a10]"
+ "|[\u0a13-\u0a28]|[\u0a2a-\u0a30]|[\u0a32-\u0a33]|[\u0a35-\u0a36]"
+ "|[\u0a38-\u0a39]|[\u0a59-\u0a5c]|\u0a5e|[\u0a72-\u0a74]|[\u0a85-\u0a8b]"
+ "|\u0a8d|[\u0a8f-\u0a91]|[\u0a93-\u0aa8]|[\u0aaa-\u0ab0]|[\u0ab2-\u0ab3]"
+ "|[\u0ab5-\u0ab9]|\u0abd|\u0ae0|[\u0b05-\u0b0c]|[\u0b0f-\u0b10]"
+ "|[\u0b13-\u0b28]|[\u0b2a-\u0b30]|[\u0b32-\u0b33]|[\u0b36-\u0b39]|\u0b3d"
+ "|[\u0b5c-\u0b5d]|[\u0b5f-\u0b61]|[\u0b85-\u0b8a]|[\u0b8e-\u0b90]"
+ "|[\u0b92-\u0b95]|[\u0b99-\u0b9a]|\u0b9c|[\u0b9e-\u0b9f]|[\u0ba3-\u0ba4]"
+ "|[\u0ba8-\u0baa]|[\u0bae-\u0bb5]|[\u0bb7-\u0bb9]|[\u0c05-\u0c0c]"
+ "|[\u0c0e-\u0c10]|[\u0c12-\u0c28]|[\u0c2a-\u0c33]|[\u0c35-\u0c39]"
+ "|[\u0c60-\u0c61]|[\u0c85-\u0c8c]|[\u0c8e-\u0c90]|[\u0c92-\u0ca8]"
+ "|[\u0caa-\u0cb3]|[\u0cb5-\u0cb9]|\u0cde|[\u0ce0-\u0ce1]|[\u0d05-\u0d0c]"
+ "|[\u0d0e-\u0d10]|[\u0d12-\u0d28]|[\u0d2a-\u0d39]|[\u0d60-\u0d61]"
+ "|[\u0e01-\u0e2e]|\u0e30|[\u0e32-\u0e33]|[\u0e40-\u0e45]|[\u0e81-\u0e82]"
+ "|\u0e84|[\u0e87-\u0e88]|\u0e8a|\u0e8d|[\u0e94-\u0e97]|[\u0e99-\u0e9f]"
+ "|[\u0ea1-\u0ea3]|\u0ea5|\u0ea7|[\u0eaa-\u0eab]|[\u0ead-\u0eae]|\u0eb0"
+ "|[\u0eb2-\u0eb3]|\u0ebd|[\u0ec0-\u0ec4]|[\u0f40-\u0f47]|[\u0f49-\u0f69]"
+ "|[\u10a0-\u10c5]|[\u10d0-\u10f6]|\u1100|[\u1102-\u1103]|[\u1105-\u1107]"
+ "|\u1109|[\u110b-\u110c]|[\u110e-\u1112]|\u113c|\u113e|\u1140|\u114c"
+ "|\u114e|\u1150|[\u1154-\u1155]|\u1159|[\u115f-\u1161]|\u1163|\u1165"
+ "|\u1167|\u1169|[\u116d-\u116e]|[\u1172-\u1173]|\u1175|\u119e|\u11a8"
+ "|\u11ab|[\u11ae-\u11af]|[\u11b7-\u11b8]|\u11ba|[\u11bc-\u11c2]|\u11eb"
+ "|\u11f0|\u11f9|[\u1e00-\u1e9b]|[\u1ea0-\u1ef9]|[\u1f00-\u1f15]"
+ "|[\u1f18-\u1f1d]|[\u1f20-\u1f45]|[\u1f48-\u1f4d]|[\u1f50-\u1f57]|\u1f59"
+ "|\u1f5b|\u1f5d|[\u1f5f-\u1f7d]|[\u1f80-\u1fb4]|[\u1fb6-\u1fbc]|\u1fbe"
+ "|[\u1fc2-\u1fc4]|[\u1fc6-\u1fcc]|[\u1fd0-\u1fd3]|[\u1fd6-\u1fdb]"
+ "|[\u1fe0-\u1fec]|[\u1ff2-\u1ff4]|[\u1ff6-\u1ffc]|\u2126|[\u212a-\u212b]"
+ "|\u212e|[\u2180-\u2182]|[\u3041-\u3094]|[\u30a1-\u30fa]|[\u3105-\u312c]"
+ "|[\uac00-\ud7a3]"
+)
+
+_PATT_IDEOGRAPHIC = "[\u4e00-\u9fa5]|\u3007|[\u3021-\u3029]"
+
+_PATT_COMBINING_CHAR = (
+ "[\u0300-\u0345]|[\u0360-\u0361]|[\u0483-\u0486]"
+ "|[\u0591-\u05a1]|[\u05a3-\u05b9]|[\u05bb-\u05bd]|\u05bf|[\u05c1-\u05c2]"
+ "|\u05c4|[\u064b-\u0652]|\u0670|[\u06d6-\u06dc]|[\u06dd-\u06df]"
+ "|[\u06e0-\u06e4]|[\u06e7-\u06e8]|[\u06ea-\u06ed]|[\u0901-\u0903]|\u093c"
+ "|[\u093e-\u094c]|\u094d|[\u0951-\u0954]|[\u0962-\u0963]|[\u0981-\u0983]"
+ "|\u09bc|\u09be|\u09bf|[\u09c0-\u09c4]|[\u09c7-\u09c8]|[\u09cb-\u09cd]"
+ "|\u09d7|[\u09e2-\u09e3]|\u0a02|\u0a3c|\u0a3e|\u0a3f|[\u0a40-\u0a42]"
+ "|[\u0a47-\u0a48]|[\u0a4b-\u0a4d]|[\u0a70-\u0a71]|[\u0a81-\u0a83]|\u0abc"
+ "|[\u0abe-\u0ac5]|[\u0ac7-\u0ac9]|[\u0acb-\u0acd]|[\u0b01-\u0b03]|\u0b3c"
+ "|[\u0b3e-\u0b43]|[\u0b47-\u0b48]|[\u0b4b-\u0b4d]|[\u0b56-\u0b57]"
+ "|[\u0b82-\u0b83]|[\u0bbe-\u0bc2]|[\u0bc6-\u0bc8]|[\u0bca-\u0bcd]|\u0bd7"
+ "|[\u0c01-\u0c03]|[\u0c3e-\u0c44]|[\u0c46-\u0c48]|[\u0c4a-\u0c4d]"
+ "|[\u0c55-\u0c56]|[\u0c82-\u0c83]|[\u0cbe-\u0cc4]|[\u0cc6-\u0cc8]"
+ "|[\u0cca-\u0ccd]|[\u0cd5-\u0cd6]|[\u0d02-\u0d03]|[\u0d3e-\u0d43]"
+ "|[\u0d46-\u0d48]|[\u0d4a-\u0d4d]|\u0d57|\u0e31|[\u0e34-\u0e3a]"
+ "|[\u0e47-\u0e4e]|\u0eb1|[\u0eb4-\u0eb9]|[\u0ebb-\u0ebc]|[\u0ec8-\u0ecd]"
+ "|[\u0f18-\u0f19]|\u0f35|\u0f37|\u0f39|\u0f3e|\u0f3f|[\u0f71-\u0f84]"
+ "|[\u0f86-\u0f8b]|[\u0f90-\u0f95]|\u0f97|[\u0f99-\u0fad]|[\u0fb1-\u0fb7]"
+ "|\u0fb9|[\u20d0-\u20dc]|\u20e1|[\u302a-\u302f]|\u3099|\u309a"
+)
+
+_PATT_DIGIT = (
+ "[\u0030-\u0039]|[\u0660-\u0669]|[\u06f0-\u06f9]|[\u0966-\u096f]"
+ "|[\u09e6-\u09ef]|[\u0a66-\u0a6f]|[\u0ae6-\u0aef]|[\u0b66-\u0b6f]"
+ "|[\u0be7-\u0bef]|[\u0c66-\u0c6f]|[\u0ce6-\u0cef]|[\u0d66-\u0d6f]"
+ "|[\u0e50-\u0e59]|[\u0ed0-\u0ed9]|[\u0f20-\u0f29]"
+)
+
+_PATT_EXTENDER = (
+ "\u00b7|\u02d0|\u02d1|\u0387|\u0640|\u0e46|\u0ec6|\u3005"
+ "|[\u3031-\u3035]|[\u309d-\u309e]|[\u30fc-\u30fe]"
+)
+
+
+PATT_LETTER = "(%s)" % "|".join([_PATT_BASE_CHAR, _PATT_IDEOGRAPHIC])
+
+PATT_NAMECHAR = "(%s)" % "|".join(
+ [PATT_LETTER, _PATT_DIGIT, ".", "-", "_", ":", _PATT_COMBINING_CHAR, _PATT_EXTENDER]
+)
+
+PATT_NAME = "(%s)(%s)+" % ("|".join([PATT_LETTER, "_", ":"]), "(%s)*" % PATT_NAMECHAR)
+
+PATT_NMTOKEN = "(%s)+" % PATT_NAMECHAR
diff --git a/spyne/const/xml_ns.py b/spyne/const/xml_ns.py
index f3949b274..47ee2af20 100644
--- a/spyne/const/xml_ns.py
+++ b/spyne/const/xml_ns.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -19,45 +18,49 @@
# This module is DEPRECATED. Use ``spyne.const.xml``.
-xml = 'http://www.w3.org/XML/1998/namespace'
-xsd = 'http://www.w3.org/2001/XMLSchema'
-xsi = 'http://www.w3.org/2001/XMLSchema-instance'
-wsa = 'http://schemas.xmlsoap.org/ws/2003/03/addressing'
-xop = 'http://www.w3.org/2004/08/xop/include'
-soap = 'http://schemas.xmlsoap.org/wsdl/soap/'
-wsdl = 'http://schemas.xmlsoap.org/wsdl/'
-xhtml = 'http://www.w3.org/1999/xhtml'
-plink = 'http://schemas.xmlsoap.org/ws/2003/05/partner-link/'
-soap11_enc = 'http://schemas.xmlsoap.org/soap/encoding/'
-soap11_env = 'http://schemas.xmlsoap.org/soap/envelope/'
-soap12_env = 'http://www.w3.org/2003/05/soap-envelope'
-soap12_enc = 'http://www.w3.org/2003/05/soap-encoding'
+xml = "http://www.w3.org/XML/1998/namespace"
+xsd = "http://www.w3.org/2001/XMLSchema"
+xsi = "http://www.w3.org/2001/XMLSchema-instance"
+wsa = "http://schemas.xmlsoap.org/ws/2003/03/addressing"
+xop = "http://www.w3.org/2004/08/xop/include"
+soap = "http://schemas.xmlsoap.org/wsdl/soap/"
+wsdl = "http://schemas.xmlsoap.org/wsdl/"
+xhtml = "http://www.w3.org/1999/xhtml"
+plink = "http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
+soap11_enc = "http://schemas.xmlsoap.org/soap/encoding/"
+soap11_env = "http://schemas.xmlsoap.org/soap/envelope/"
+soap12_env = "http://www.w3.org/2003/05/soap-envelope"
+soap12_enc = "http://www.w3.org/2003/05/soap-encoding"
const_nsmap = {
- 'xml': xml,
- 'xs': xsd,
- 'xsi': xsi,
- 'plink': plink,
- 'soap': soap,
- 'wsdl': wsdl,
- 'soap11enc': soap11_enc,
- 'soap11env': soap11_env,
- 'soap12env': soap12_env,
- 'soap12enc': soap12_enc,
- 'wsa': wsa,
- 'xop': xop,
+ "xml": xml,
+ "xs": xsd,
+ "xsi": xsi,
+ "plink": plink,
+ "soap": soap,
+ "wsdl": wsdl,
+ "soap11enc": soap11_enc,
+ "soap11env": soap11_env,
+ "soap12env": soap12_env,
+ "soap12enc": soap12_enc,
+ "wsa": wsa,
+ "xop": xop,
}
const_prefmap = None
+
+
def regen_prefmap():
global const_prefmap
const_prefmap = dict([(b, a) for a, b in const_nsmap.items()])
+
regen_prefmap()
schema_location = {
- xsd: 'http://www.w3.org/2001/XMLSchema.xsd',
+ xsd: "http://www.w3.org/2001/XMLSchema.xsd",
}
+
class DEFAULT_NS(object):
pass
diff --git a/spyne/context.py b/spyne/context.py
index 3f255d9b5..4f78ea662 100644
--- a/spyne/context.py
+++ b/spyne/context.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -17,21 +16,23 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
-import gc, logging
-logger = logging.getLogger('spyne')
+import gc
+import logging
-from time import time
+logger = logging.getLogger("spyne")
+
+from collections import defaultdict, deque
from copy import copy
-from collections import deque, defaultdict
+from time import time
from spyne import const
-
_LAST_GC_RUN = 0.0
class AuxMethodContext(object):
"""Generic object that holds information specific to auxiliary methods"""
+
def __init__(self, parent, error):
self.parent = parent
"""Primary context that this method was bound to."""
@@ -42,6 +43,7 @@ def __init__(self, parent, error):
class TransportContext(object):
"""Generic object that holds transport-specific context information"""
+
def __init__(self, parent, transport, type=None):
self.parent = parent
"""The MethodContext this object belongs to"""
@@ -61,7 +63,7 @@ def __init__(self, parent, transport, type=None):
self.remote_addr = None
"""The address of the other end of the connection."""
- self.sessid = ''
+ self.sessid = ""
"""The session id."""
def get_peer(self):
@@ -73,6 +75,7 @@ def get_peer(self):
class ProtocolContext(object):
"""Generic object that holds protocol-specific context information"""
+
def __init__(self, parent, transport, type=None):
self.parent = parent
"""The MethodContext this object belongs to"""
@@ -84,8 +87,7 @@ def __init__(self, parent, transport, type=None):
self.type = type
"""The protocol the transport uses."""
- self._subctx = defaultdict(
- lambda: self.__class__(parent, transport, type))
+ self._subctx = defaultdict(lambda: self.__class__(parent, transport, type))
def __getitem__(self, item):
return self._subctx[item]
@@ -93,6 +95,7 @@ def __getitem__(self, item):
class EventContext(object):
"""Generic object that holds event-specific context information"""
+
def __init__(self, parent, event_id=None):
self.parent = parent
self.event_id = event_id
@@ -357,33 +360,33 @@ def service_class(self):
return self.descriptor.service_class
def __setattr__(self, k, v):
- if not self.frozen or k in self.__dict__ or k in \
- ('descriptor', 'out_protocol'):
+ if not self.frozen or k in self.__dict__ or k in ("descriptor", "out_protocol"):
object.__setattr__(self, k, v)
else:
- raise ValueError("use the udc member for storing arbitrary data "
- "in the method context")
+ raise ValueError(
+ "use the udc member for storing arbitrary data " "in the method context"
+ )
def __repr__(self):
retval = deque()
for k, v in self.__dict__.items():
if isinstance(v, dict):
- ret = deque(['{'])
+ ret = deque(["{"])
for k2, v2 in sorted(v.items()):
- ret.append('\t\t%r: %r,' % (k2, v2))
+ ret.append("\t\t%r: %r," % (k2, v2))
- ret.append('\t}')
- ret = '\n'.join(ret)
+ ret.append("\t}")
+ ret = "\n".join(ret)
retval.append("\n\t%s=%s" % (k, ret))
else:
retval.append("\n\t%s=%r" % (k, v))
- retval.append('\n)')
+ retval.append("\n)")
- return ''.join((self.__class__.__name__, '(', ', '.join(retval), ')'))
+ return "".join((self.__class__.__name__, "(", ", ".join(retval), ")"))
def close(self):
global _LAST_GC_RUN
@@ -400,7 +403,7 @@ def close(self):
if (t - _LAST_GC_RUN) > const.MIN_GC_INTERVAL:
gc.collect()
- dt = (time() - t)
+ dt = time() - t
_LAST_GC_RUN = t
logger.debug("gc.collect() took around %dms.", round(dt, 2) * 1000)
@@ -426,10 +429,22 @@ def get_in_protocol(self):
class FakeContext(object):
- def __init__(self, app=None, descriptor=None, in_header=None,
- in_object=None, in_error=None, in_document=None, in_string=None,
- out_object=None, out_error=None, out_document=None, out_string=None,
- in_protocol=None, out_protocol=None):
+ def __init__(
+ self,
+ app=None,
+ descriptor=None,
+ in_header=None,
+ in_object=None,
+ in_error=None,
+ in_document=None,
+ in_string=None,
+ out_object=None,
+ out_error=None,
+ out_document=None,
+ out_string=None,
+ in_protocol=None,
+ out_protocol=None,
+ ):
self.app = app
self.descriptor = descriptor
self.in_header = in_header
diff --git a/spyne/decorator.py b/spyne/decorator.py
index 38ad8ccf7..fb1b37f2d 100644
--- a/spyne/decorator.py
+++ b/spyne/decorator.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -26,31 +25,39 @@
decorator is a simple example of this.
"""
-import spyne.const.xml
-
from copy import copy
from inspect import isclass
-from spyne import MethodDescriptor
+import spyne.const.xml
# Empty means empty input, bare output. Doesn't say anything about response
# being empty
from spyne import LogicError
-from spyne import BODY_STYLE_EMPTY
-from spyne import BODY_STYLE_WRAPPED
-from spyne import BODY_STYLE_BARE
-from spyne import BODY_STYLE_OUT_BARE
-from spyne import BODY_STYLE_EMPTY_OUT_BARE
-
-from spyne.model import ModelBase, ComplexModel, ComplexModelBase
-from spyne.model.complex import TypeInfo, recust_selfref, SelfReference
-
from spyne.const import add_request_suffix
-
-
-def _produce_input_message(f, params, in_message_name, in_variable_names,
- no_ctx, no_self, argnames, body_style_str, self_ref_cls,
- in_wsdl_part_name):
+from spyne.descriptor import (
+ BODY_STYLE_BARE,
+ BODY_STYLE_EMPTY,
+ BODY_STYLE_EMPTY_OUT_BARE,
+ BODY_STYLE_OUT_BARE,
+ BODY_STYLE_WRAPPED,
+ MethodDescriptor,
+)
+from spyne.model import ComplexModel, ComplexModelBase, ModelBase
+from spyne.model.complex import SelfReference, TypeInfo, recust_selfref
+
+
+def _produce_input_message(
+ f,
+ params,
+ in_message_name,
+ in_variable_names,
+ no_ctx,
+ no_self,
+ argnames,
+ body_style_str,
+ self_ref_cls,
+ in_wsdl_part_name,
+):
arg_start = 0
if no_ctx is False:
arg_start += 1
@@ -72,21 +79,25 @@ def _produce_input_message(f, params, in_message_name, in_variable_names,
if no_self is False:
params = [self_ref_cls.novalidate_freq()] + params
- argnames = ('self',) + argnames
+ argnames = ("self",) + argnames
if len(params) != len(argnames):
- raise LogicError("%r function has %d argument(s) but its decorator "
- "has %d." % (f.__name__, len(argnames), len(params)))
+ raise LogicError(
+ "%r function has %d argument(s) but its decorator "
+ "has %d." % (f.__name__, len(argnames), len(params))
+ )
else:
argnames = copy(argnames)
if len(params) != len(argnames):
- raise LogicError("%r function has %d argument(s) but the _args "
- "argument has %d." % (
- f.__name__, len(argnames), len(params)))
+ raise LogicError(
+ "%r function has %d argument(s) but the _args "
+ "argument has %d." % (f.__name__, len(argnames), len(params))
+ )
in_params = TypeInfo()
from spyne import SelfReference
+
for k, v in zip(argnames, params):
try:
is_self_ref = issubclass(v, SelfReference)
@@ -106,7 +117,7 @@ def _produce_input_message(f, params, in_message_name, in_variable_names,
ns, _, in_message_name = in_message_name[1:].partition("}")
message = None
- if body_style_str == 'bare':
+ if body_style_str == "bare":
if len(in_params) > 1:
# The soap Body elt contains 1 elt (called "body entry" in the soap
# standard) per method call. If bare methods were allowed to have >1
@@ -114,28 +125,33 @@ def _produce_input_message(f, params, in_message_name, in_variable_names,
# which would violate the standard. It's easy to work around this
# restriction by creating a ComplexModel that contains all the
# required parameters.
- raise LogicError("body_style='bare' can handle at most one "
- "function argument.")
+ raise LogicError(
+ "body_style='bare' can handle at most one " "function argument."
+ )
if len(in_params) == 0:
- message = ComplexModel.produce(type_name=in_message_name,
- namespace=ns, members=in_params)
+ message = ComplexModel.produce(
+ type_name=in_message_name, namespace=ns, members=in_params
+ )
else:
- message, = in_params.values()
+ (message,) = in_params.values()
message = message.customize(sub_name=in_message_name, sub_ns=ns)
if issubclass(message, ComplexModelBase) and not message._type_info:
- raise LogicError("body_style='bare' does not allow empty "
- "model as param")
+ raise LogicError(
+ "body_style='bare' does not allow empty " "model as param"
+ )
# there can't be multiple arguments here.
if message.__type_name__ is ModelBase.Empty:
- message._fill_empty_type_name(ns, in_message_name,
- "%s_arg0" % in_message_name)
+ message._fill_empty_type_name(
+ ns, in_message_name, "%s_arg0" % in_message_name
+ )
else:
- message = ComplexModel.produce(type_name=in_message_name,
- namespace=ns, members=in_params)
+ message = ComplexModel.produce(
+ type_name=in_message_name, namespace=ns, members=in_params
+ )
message.__namespace__ = ns
if in_wsdl_part_name:
@@ -145,22 +161,21 @@ def _produce_input_message(f, params, in_message_name, in_variable_names,
def _validate_body_style(kparams):
- _body_style = kparams.pop('_body_style', None)
- _soap_body_style = kparams.pop('_soap_body_style', None)
+ _body_style = kparams.pop("_body_style", None)
+ _soap_body_style = kparams.pop("_soap_body_style", None)
- allowed_body_styles = ('wrapped', 'bare', 'out_bare')
+ allowed_body_styles = ("wrapped", "bare", "out_bare")
if _body_style is None:
- _body_style = 'wrapped'
+ _body_style = "wrapped"
elif not (_body_style in allowed_body_styles):
- raise ValueError("body_style must be one of %r" %
- (allowed_body_styles,))
+ raise ValueError("body_style must be one of %r" % (allowed_body_styles,))
- elif _soap_body_style == 'document':
- _body_style = 'wrapped'
+ elif _soap_body_style == "document":
+ _body_style = "wrapped"
- elif _soap_body_style == 'rpc':
- _body_style = 'bare'
+ elif _soap_body_style == "rpc":
+ _body_style = "bare"
elif _soap_body_style is None:
pass
@@ -168,19 +183,18 @@ def _validate_body_style(kparams):
else:
raise ValueError("soap_body_style must be one of ('rpc', 'document')")
- assert _body_style in ('wrapped', 'bare', 'out_bare')
+ assert _body_style in ("wrapped", "bare", "out_bare")
return _body_style
-def _produce_output_message(func_name, body_style_str, self_ref_cls,
- no_self, kparams):
+def _produce_output_message(func_name, body_style_str, self_ref_cls, no_self, kparams):
"""Generate an output message for "rpc"-style API methods.
This message is a wrapper to the declared return type.
"""
- _returns = kparams.pop('_returns', None)
+ _returns = kparams.pop("_returns", None)
try:
is_self_ref = issubclass(_returns, SelfReference)
@@ -193,35 +207,38 @@ def _produce_output_message(func_name, body_style_str, self_ref_cls,
_returns = recust_selfref(_returns, self_ref_cls)
- _is_out_message_name_overridden = not ('_out_message_name' in kparams)
- _out_message_name = kparams.pop('_out_message_name', '%s%s' %
- (func_name, spyne.const.RESPONSE_SUFFIX))
+ _is_out_message_name_overridden = not ("_out_message_name" in kparams)
+ _out_message_name = kparams.pop(
+ "_out_message_name", "%s%s" % (func_name, spyne.const.RESPONSE_SUFFIX)
+ )
- if no_self is False and \
- (body_style_str == 'wrapped' or _is_out_message_name_overridden):
- _out_message_name = '%s.%s' % \
- (self_ref_cls.get_type_name(), _out_message_name)
+ if no_self is False and (
+ body_style_str == "wrapped" or _is_out_message_name_overridden
+ ):
+ _out_message_name = "%s.%s" % (self_ref_cls.get_type_name(), _out_message_name)
- _out_wsdl_part_name = kparams.pop('_wsdl_part_name', None)
+ _out_wsdl_part_name = kparams.pop("_wsdl_part_name", None)
out_params = TypeInfo()
- if _returns and body_style_str == 'wrapped':
+ if _returns and body_style_str == "wrapped":
if isinstance(_returns, (list, tuple)):
- default_names = ['%s%s%d'% (func_name, spyne.const.RESULT_SUFFIX, i)
- for i in range(len(_returns))]
+ default_names = [
+ "%s%s%d" % (func_name, spyne.const.RESULT_SUFFIX, i)
+ for i in range(len(_returns))
+ ]
- _out_variable_names = kparams.pop('_out_variable_names',
- default_names)
+ _out_variable_names = kparams.pop("_out_variable_names", default_names)
- assert (len(_returns) == len(_out_variable_names))
+ assert len(_returns) == len(_out_variable_names)
var_pair = zip(_out_variable_names, _returns)
out_params = TypeInfo(var_pair)
else:
- _out_variable_name = kparams.pop('_out_variable_name',
- '%s%s' % (func_name, spyne.const.RESULT_SUFFIX))
+ _out_variable_name = kparams.pop(
+ "_out_variable_name", "%s%s" % (func_name, spyne.const.RESULT_SUFFIX)
+ )
out_params[_out_variable_name] = _returns
@@ -231,14 +248,15 @@ def _produce_output_message(func_name, body_style_str, self_ref_cls,
ns = _out_message_name_parts[0] # skip index 1, it is the closing '}'
_out_message_name = _out_message_name_parts[2]
- if body_style_str.endswith('bare') and _returns is not None:
+ if body_style_str.endswith("bare") and _returns is not None:
message = _returns.customize(sub_name=_out_message_name, sub_ns=ns)
if message.__type_name__ is ModelBase.Empty:
message.__type_name__ = _out_message_name
else:
- message = ComplexModel.produce(type_name=_out_message_name,
- namespace=ns, members=out_params)
+ message = ComplexModel.produce(
+ type_name=_out_message_name, namespace=ns, members=out_params
+ )
message.Attributes._wrapper = True
message.__namespace__ = ns # FIXME: is this necessary?
@@ -283,15 +301,18 @@ def _get_event_managers(kparams):
_event_managers = kparams.pop("_event_managers", None)
if _event_manager is not None and _event_managers is not None:
- raise LogicError("Pass one of _event_manager or "
- "_event_managers but not both")
+ raise LogicError(
+ "Pass one of _event_manager or " "_event_managers but not both"
+ )
if _event_manager is not None:
_event_managers = [_event_manager]
if _evmgrs is not None and _event_managers is not None:
- raise LogicError("You must pass at most one of _evmgr* "
- "arguments or _event_manager* arguments")
+ raise LogicError(
+ "You must pass at most one of _evmgr* "
+ "arguments or _event_manager* arguments"
+ )
elif _evmgrs is not None:
_event_managers = _evmgrs
@@ -384,19 +405,19 @@ def explain_method(**kwargs):
# contains information about the method context like the service
# class that contains the method at hand.
- function_name = kwargs['_default_function_name']
+ function_name = kwargs["_default_function_name"]
_service_class = kwargs.pop("_service_class", None)
_self_ref_replacement = None
# this block is passed straight to the descriptor
- _is_callback = kparams.pop('_is_callback', False)
- _is_async = kparams.pop('_is_async', False)
- _mtom = kparams.pop('_mtom', False)
- _in_header = kparams.pop('_in_header', None)
- _out_header = kparams.pop('_out_header', None)
- _port_type = kparams.pop('_port_type', None)
- _no_ctx = kparams.pop('_no_ctx', False)
- _aux = kparams.pop('_aux', None)
+ _is_callback = kparams.pop("_is_callback", False)
+ _is_async = kparams.pop("_is_async", False)
+ _mtom = kparams.pop("_mtom", False)
+ _in_header = kparams.pop("_in_header", None)
+ _out_header = kparams.pop("_out_header", None)
+ _port_type = kparams.pop("_port_type", None)
+ _no_ctx = kparams.pop("_no_ctx", False)
+ _aux = kparams.pop("_aux", None)
_pattern = kparams.pop("_pattern", None)
_patterns = kparams.pop("_patterns", [])
_args = kparams.pop("_args", None)
@@ -405,132 +426,162 @@ def explain_method(**kwargs):
_static_when = kparams.pop("_static_when", None)
_href = kparams.pop("_href", None)
_logged = kparams.pop("_logged", True)
- _internal_key_suffix = kparams.pop('_internal_key_suffix', '')
- if '_service' in kparams and '_service_class' in kparams:
- raise LogicError("Please pass only one of '_service' and "
- "'_service_class'")
- if '_service' in kparams:
+ _internal_key_suffix = kparams.pop("_internal_key_suffix", "")
+ if "_service" in kparams and "_service_class" in kparams:
+ raise LogicError(
+ "Please pass only one of '_service' and " "'_service_class'"
+ )
+ if "_service" in kparams:
_service_class = kparams.pop("_service")
- if '_service_class' in kparams:
+ if "_service_class" in kparams:
_service_class = kparams.pop("_service_class")
- _no_self = kparams.pop('_no_self', True)
+ _no_self = kparams.pop("_no_self", True)
_event_managers = _get_event_managers(kparams)
# mrpc-specific
- _self_ref_replacement = kwargs.pop('_self_ref_replacement', None)
- _default_on_null = kparams.pop('_default_on_null', False)
- _substitute_self_reference(params, kparams, _self_ref_replacement,
- _no_self)
+ _self_ref_replacement = kwargs.pop("_self_ref_replacement", None)
+ _default_on_null = kparams.pop("_default_on_null", False)
+ _substitute_self_reference(params, kparams, _self_ref_replacement, _no_self)
_faults = None
- if ('_faults' in kparams) and ('_throws' in kparams):
- raise ValueError("only one of '_throws ' or '_faults' arguments"
- "must be given -- they're synonyms.")
+ if ("_faults" in kparams) and ("_throws" in kparams):
+ raise ValueError(
+ "only one of '_throws ' or '_faults' arguments"
+ "must be given -- they're synonyms."
+ )
- elif '_faults' in kparams:
- _faults = kparams.pop('_faults')
+ elif "_faults" in kparams:
+ _faults = kparams.pop("_faults")
- elif '_throws' in kparams:
- _faults = kparams.pop('_throws')
+ elif "_throws" in kparams:
+ _faults = kparams.pop("_throws")
- _is_in_message_name_overridden = not ('_in_message_name' in kparams)
- _in_message_name = kparams.pop('_in_message_name', function_name)
+ _is_in_message_name_overridden = not ("_in_message_name" in kparams)
+ _in_message_name = kparams.pop("_in_message_name", function_name)
if _no_self is False and _is_in_message_name_overridden:
- _in_message_name = '%s.%s' % \
- (_self_ref_replacement.get_type_name(), _in_message_name)
+ _in_message_name = "%s.%s" % (
+ _self_ref_replacement.get_type_name(),
+ _in_message_name,
+ )
- _operation_name = kparams.pop('_operation_name', function_name)
+ _operation_name = kparams.pop("_operation_name", function_name)
- if _operation_name != function_name and \
- _in_message_name != function_name:
+ if _operation_name != function_name and _in_message_name != function_name:
raise ValueError(
"only one of '_operation_name' and '_in_message_name' "
- "arguments should be given")
+ "arguments should be given"
+ )
if _in_message_name == function_name:
_in_message_name = add_request_suffix(_operation_name)
- if '_in_arg_names' in kparams and '_in_variable_names' in kparams:
- raise LogicError("Use either '_in_arg_names' or "
- "'_in_variable_names', not both.")
- elif '_in_arg_names' in kparams:
- _in_arg_names = kparams.pop('_in_arg_names')
+ if "_in_arg_names" in kparams and "_in_variable_names" in kparams:
+ raise LogicError(
+ "Use either '_in_arg_names' or " "'_in_variable_names', not both."
+ )
+ elif "_in_arg_names" in kparams:
+ _in_arg_names = kparams.pop("_in_arg_names")
- elif '_in_variable_names' in kparams:
- _in_arg_names = kparams.pop('_in_variable_names')
+ elif "_in_variable_names" in kparams:
+ _in_arg_names = kparams.pop("_in_variable_names")
else:
_in_arg_names = {}
- if '_udd' in kparams and '_udp' in kparams:
+ if "_udd" in kparams and "_udp" in kparams:
raise LogicError("Use either '_udd' or '_udp', not both.")
- elif '_udd' in kparams:
- _udd = kparams.pop('_udd')
+ elif "_udd" in kparams:
+ _udd = kparams.pop("_udd")
- elif '_udp' in kparams:
- _udd = kparams.pop('_udp')
+ elif "_udp" in kparams:
+ _udd = kparams.pop("_udp")
else:
_udd = {}
- _wsdl_part_name = kparams.get('_wsdl_part_name', None)
+ _wsdl_part_name = kparams.get("_wsdl_part_name", None)
body_style = BODY_STYLE_WRAPPED
body_style_str = _validate_body_style(kparams)
- if body_style_str.endswith('bare'):
- if body_style_str == 'out_bare':
+ if body_style_str.endswith("bare"):
+ if body_style_str == "out_bare":
body_style = BODY_STYLE_OUT_BARE
else:
body_style = BODY_STYLE_BARE
- in_message = _produce_input_message(f, params,
- _in_message_name, _in_arg_names, _no_ctx, _no_self,
- _args, body_style_str, _self_ref_replacement,
- _wsdl_part_name)
+ in_message = _produce_input_message(
+ f,
+ params,
+ _in_message_name,
+ _in_arg_names,
+ _no_ctx,
+ _no_self,
+ _args,
+ body_style_str,
+ _self_ref_replacement,
+ _wsdl_part_name,
+ )
- out_message = _produce_output_message(function_name,
- body_style_str, _self_ref_replacement, _no_self, kparams)
+ out_message = _produce_output_message(
+ function_name, body_style_str, _self_ref_replacement, _no_self, kparams
+ )
if _logged != True:
in_message.Attributes.logged = _logged
out_message.Attributes.logged = _logged
- doc = getattr(f, '__doc__')
+ doc = getattr(f, "__doc__")
if _pattern is not None and _patterns != []:
- raise ValueError("only one of '_pattern' and '_patterns' "
- "arguments should be given")
+ raise ValueError(
+ "only one of '_pattern' and '_patterns' "
+ "arguments should be given"
+ )
if _pattern is not None:
_patterns = [_pattern]
- if body_style_str.endswith('bare'):
+ if body_style_str.endswith("bare"):
from spyne.model import ComplexModelBase
ti = in_message
to = out_message
if issubclass(ti, ComplexModelBase) and len(ti._type_info) == 0:
- if not issubclass(to, ComplexModelBase) or \
- len(to._type_info) > 0:
+ if not issubclass(to, ComplexModelBase) or len(to._type_info) > 0:
body_style = BODY_STYLE_EMPTY_OUT_BARE
else:
body_style = BODY_STYLE_EMPTY
assert _in_header is None or isinstance(_in_header, tuple)
- retval = MethodDescriptor(f,
- in_message, out_message, doc,
- is_callback=_is_callback, is_async=_is_async, mtom=_mtom,
- in_header=_in_header, out_header=_out_header, faults=_faults,
+ retval = MethodDescriptor(
+ f,
+ in_message,
+ out_message,
+ doc,
+ is_callback=_is_callback,
+ is_async=_is_async,
+ mtom=_mtom,
+ in_header=_in_header,
+ out_header=_out_header,
+ faults=_faults,
parent_class=_self_ref_replacement,
- port_type=_port_type, no_ctx=_no_ctx, udd=_udd,
- class_key=function_name, aux=_aux, patterns=_patterns,
- body_style=body_style, args=_args,
- operation_name=_operation_name, no_self=_no_self,
+ port_type=_port_type,
+ no_ctx=_no_ctx,
+ udd=_udd,
+ class_key=function_name,
+ aux=_aux,
+ patterns=_patterns,
+ body_style=body_style,
+ args=_args,
+ operation_name=_operation_name,
+ no_self=_no_self,
translations=_translations,
- when=_when, static_when=_static_when,
- service_class=_service_class, href=_href,
+ when=_when,
+ static_when=_static_when,
+ service_class=_service_class,
+ href=_href,
internal_key_suffix=_internal_key_suffix,
default_on_null=_default_on_null,
event_managers=_event_managers,
diff --git a/spyne/descriptor.py b/spyne/descriptor.py
index 41804e955..4b2c5be99 100644
--- a/spyne/descriptor.py
+++ b/spyne/descriptor.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,20 +17,33 @@
#
import logging
-logger = logging.getLogger('spyne')
+
+logger = logging.getLogger("spyne")
from spyne import LogicError
-from spyne.util import six
-from spyne.util import DefaultAttrDict
-from spyne.service import Service, ServiceBaseBase
from spyne.const.xml import DEFAULT_NS
+from spyne.service import Service, ServiceBaseBase
+from spyne.util import DefaultAttrDict
+
+
+class BODY_STYLE_WRAPPED:
+ pass
-class BODY_STYLE_WRAPPED: pass
-class BODY_STYLE_EMPTY: pass
-class BODY_STYLE_BARE: pass
-class BODY_STYLE_OUT_BARE: pass
-class BODY_STYLE_EMPTY_OUT_BARE: pass
+class BODY_STYLE_EMPTY:
+ pass
+
+
+class BODY_STYLE_BARE:
+ pass
+
+
+class BODY_STYLE_OUT_BARE:
+ pass
+
+
+class BODY_STYLE_EMPTY_OUT_BARE:
+ pass
class MethodDescriptor(object):
@@ -39,12 +51,39 @@ class MethodDescriptor(object):
produced by the :func:`spyne.decorator.srpc` decorator.
"""
- def __init__(self, function, in_message, out_message, doc,
- is_callback, is_async, mtom, in_header, out_header, faults,
- parent_class, port_type, no_ctx, udd, class_key, aux, patterns,
- body_style, args, operation_name, no_self, translations,
- when, static_when, service_class, href, internal_key_suffix,
- default_on_null, event_managers, logged):
+ def __init__(
+ self,
+ function,
+ in_message,
+ out_message,
+ doc,
+ is_callback,
+ is_async,
+ mtom,
+ in_header,
+ out_header,
+ faults,
+ parent_class,
+ port_type,
+ no_ctx,
+ udd,
+ class_key,
+ aux,
+ patterns,
+ body_style,
+ args,
+ operation_name,
+ no_self,
+ translations,
+ when,
+ static_when,
+ service_class,
+ href,
+ internal_key_suffix,
+ default_on_null,
+ event_managers,
+ logged,
+ ):
self.__real_function = function
"""The original callable for the user code."""
@@ -86,9 +125,9 @@ def __init__(self, function, in_message, out_message, doc,
self.is_callback = is_callback
self.is_async = is_async
self.mtom = mtom
- #"""Flag to indicate whether to use MTOM transport with SOAP."""
+ # """Flag to indicate whether to use MTOM transport with SOAP."""
self.port_type = port_type
- #"""The portType this function belongs to."""
+ # """The portType this function belongs to."""
self.in_header = in_header
"""An iterable of :class:`spyne.model.complex.ComplexModel`
@@ -194,7 +233,7 @@ def translate(self, locale, default):
"""
if locale is None:
- locale = 'en_US'
+ locale = "en_US"
if self.translations is not None:
return self.translations.get(locale, default)
return default
@@ -205,8 +244,10 @@ def key(self):
assert not (self.in_message.get_namespace() is DEFAULT_NS)
- return '{%s}%s' % (
- self.in_message.get_namespace(), self.in_message.get_type_name())
+ return "{%s}%s" % (
+ self.in_message.get_namespace(),
+ self.in_message.get_type_name(),
+ )
@property
def internal_key(self):
@@ -220,16 +261,18 @@ def internal_key(self):
dn = self.name
# prevent duplicate class name. this happens when the class is a
# direct subclass of ComplexModel
- if dn.split('.', 1)[0] != on:
+ if dn.split(".", 1)[0] != on:
return "{%s}%s.%s" % (mn, on, dn)
return "{%s}%s" % (mn, dn)
sc = self.service_class
if sc is not None:
- return '{%s}%s%s' % (sc.get_internal_key(),
- six.get_function_name(self.function),
- self.internal_key_suffix)
+ return "{%s}%s%s" % (
+ sc.get_internal_key(),
+ self.function.__name__,
+ self.internal_key_suffix,
+ )
@staticmethod
def get_owner_name(cls):
@@ -240,32 +283,36 @@ def get_owner_name(cls):
def gen_interface_key(self, cls):
# this is a regular service method decorated by @rpc
if issubclass(cls, ServiceBaseBase):
- return u'{}.{}.{}'.format(cls.__module__,
- self.get_owner_name(cls), self.name)
+ return "{}.{}.{}".format(
+ cls.__module__, self.get_owner_name(cls), self.name
+ )
# this is a member method decorated by @mrpc
else:
- mn = cls.get_namespace() or '__none__'
+ mn = cls.get_namespace() or "__none__"
on = cls.get_type_name()
dn = self.name
# prevent duplicate class name. this happens when the class is a
# direct subclass of ComplexModel
- if dn.split(u'.', 1)[0] != on:
- return u'.'.join( (mn, on, dn) )
+ if dn.split(".", 1)[0] != on:
+ return ".".join((mn, on, dn))
- return u'.'.join( (mn, dn) )
+ return ".".join((mn, dn))
@staticmethod
def _get_class_module_name(cls):
- return '.'.join([frag for frag in cls.__module__.split('.')
- if not frag.startswith('_')])
+ return ".".join(
+ [frag for frag in cls.__module__.split(".") if not frag.startswith("_")]
+ )
def is_out_bare(self):
- return self.body_style in (BODY_STYLE_EMPTY_OUT_BARE,
- BODY_STYLE_EMPTY,
- BODY_STYLE_BARE,
- BODY_STYLE_OUT_BARE)
+ return self.body_style in (
+ BODY_STYLE_EMPTY_OUT_BARE,
+ BODY_STYLE_EMPTY,
+ BODY_STYLE_BARE,
+ BODY_STYLE_OUT_BARE,
+ )
def reset_function(self, val=None):
if val != None:
@@ -279,6 +326,7 @@ def in_header(self):
@in_header.setter
def in_header(self, in_header):
from spyne.model._base import ModelBase
+
try:
is_model = issubclass(in_header, ModelBase)
except TypeError:
@@ -297,6 +345,7 @@ def out_header(self):
@out_header.setter
def out_header(self, out_header):
from spyne.model._base import ModelBase
+
try:
is_model = issubclass(out_header, ModelBase)
except TypeError:
diff --git a/spyne/error.py b/spyne/error.py
index 20cfd793c..35102f393 100644
--- a/spyne/error.py
+++ b/spyne/error.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -22,24 +21,25 @@
code can throw.
"""
-from spyne.model.fault import Fault
+from spyne.model.fault import Fault, ValidationError
class InvalidCredentialsError(Fault):
"""Raised when requested resource is forbidden."""
- CODE = 'Client.InvalidCredentialsError'
+ CODE = "Client.InvalidCredentialsError"
STR = "You do not have permission to access this resource."
def __init__(self, fault_string=STR, params=None):
- super(InvalidCredentialsError, self) \
- .__init__(self.CODE, fault_string, detail=params)
+ super(InvalidCredentialsError, self).__init__(
+ self.CODE, fault_string, detail=params
+ )
class RequestTooLongError(Fault):
"""Raised when request is too long."""
- CODE = 'Client.RequestTooLong'
+ CODE = "Client.RequestTooLong"
def __init__(self, faultstring="Request too long"):
super(RequestTooLongError, self).__init__(self.CODE, faultstring)
@@ -48,7 +48,7 @@ def __init__(self, faultstring="Request too long"):
class RequestNotAllowed(Fault):
"""Raised when request is incomplete."""
- CODE = 'Client.RequestNotAllowed'
+ CODE = "Client.RequestNotAllowed"
def __init__(self, faultstring=""):
super(RequestNotAllowed, self).__init__(self.CODE, faultstring)
@@ -57,7 +57,7 @@ def __init__(self, faultstring=""):
class ArgumentError(Fault):
"""Raised when there is a general problem with input data."""
- CODE = 'Client.ArgumentError'
+ CODE = "Client.ArgumentError"
def __init__(self, faultstring=""):
super(ArgumentError, self).__init__(self.CODE, faultstring)
@@ -67,8 +67,9 @@ class InvalidInputError(Fault):
"""Raised when there is a general problem with input data."""
def __init__(self, faultstring="", data=""):
- super(InvalidInputError, self) \
- .__init__('Client.InvalidInput', repr((faultstring, data)))
+ super(InvalidInputError, self).__init__(
+ "Client.InvalidInput", repr((faultstring, data))
+ )
InvalidRequestError = InvalidInputError
@@ -77,7 +78,7 @@ def __init__(self, faultstring="", data=""):
class MissingFieldError(InvalidInputError):
"""Raised when a mandatory value is missing."""
- CODE = 'Client.InvalidInput'
+ CODE = "Client.InvalidInput"
def __init__(self, field_name, message="Field '%s' is missing."):
try:
@@ -88,39 +89,26 @@ def __init__(self, field_name, message="Field '%s' is missing."):
super(MissingFieldError, self).__init__(self.CODE, message)
-class ValidationError(Fault):
- """Raised when the input stream does not adhere to type constraints."""
-
- CODE = 'Client.ValidationError'
-
- def __init__(self, obj, custom_msg='The value %r could not be validated.'):
- try:
- msg = custom_msg % (obj,)
- except TypeError:
- msg = custom_msg
-
- super(ValidationError, self).__init__(self.CODE, msg)
-
-
class InternalError(Fault):
"""Raised to communicate server-side errors."""
- CODE = 'Server'
+ CODE = "Server"
def __init__(self, error):
- super(InternalError, self) \
- .__init__(self.CODE, "InternalError: An unknown error has occured.")
+ super(InternalError, self).__init__(
+ self.CODE, "InternalError: An unknown error has occured."
+ )
class ResourceNotFoundError(Fault):
"""Raised when requested resource is not found."""
- CODE = 'Client.ResourceNotFound'
+ CODE = "Client.ResourceNotFound"
- def __init__(self, fault_object,
- fault_string="Requested resource %r not found"):
- super(ResourceNotFoundError, self) \
- .__init__(self.CODE, fault_string % (fault_object,))
+ def __init__(self, fault_object, fault_string="Requested resource %r not found"):
+ super(ResourceNotFoundError, self).__init__(
+ self.CODE, fault_string % (fault_object,)
+ )
class RespawnError(ResourceNotFoundError):
@@ -130,18 +118,19 @@ class RespawnError(ResourceNotFoundError):
class ResourceAlreadyExistsError(Fault):
"""Raised when requested resource already exists on server side."""
- CODE = 'Client.ResourceAlreadyExists'
+ CODE = "Client.ResourceAlreadyExists"
def __init__(self, fault_object, fault_string="Resource %r already exists"):
- super(ResourceAlreadyExistsError, self) \
- .__init__(self.CODE, fault_string % fault_object)
+ super(ResourceAlreadyExistsError, self).__init__(
+ self.CODE, fault_string % fault_object
+ )
class Redirect(Fault):
"""Raised when client needs to make another request for the same
resource."""
- CODE = 'Client.Redirect'
+ CODE = "Client.Redirect"
def __init__(self, ctx, location, orig_exc=None):
super(Redirect, self).__init__(self.CODE, faultstring=location)
diff --git a/spyne/evmgr.py b/spyne/evmgr.py
index 6b2250dcc..d9ac9c9bf 100644
--- a/spyne/evmgr.py
+++ b/spyne/evmgr.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -68,7 +67,6 @@ def del_listener(self, event_name, handler=None):
else:
self.handlers[event_name].remove(handler)
-
def fire_event(self, event_name, ctx, *args, **kwargs):
"""Run all the handlers for a given event name.
diff --git a/spyne/interface/__init__.py b/spyne/interface/__init__.py
index dd88cdb21..2510faa41 100644
--- a/spyne/interface/__init__.py
+++ b/spyne/interface/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -24,22 +23,23 @@
to generate those documents.
"""
-
from __future__ import print_function
-from spyne.interface._base import Interface
-from spyne.interface._base import InterfaceDocumentBase
-from spyne.interface._base import InterfaceDocumentsBase
-from spyne.interface._base import InterfaceDocuments
-
+from spyne.interface._base import (
+ Interface,
+ InterfaceDocumentBase,
+ InterfaceDocuments,
+ InterfaceDocumentsBase,
+)
try:
- from spyne.interface.xml_schema import XmlSchema
from spyne.interface.wsdl.wsdl11 import Wsdl11
+ from spyne.interface.xml_schema import XmlSchema
+
HAS_WSDL = True
except ImportError as e:
- if 'No module named lxml' in e.args or "No module named 'lxml'" in e.args:
+ if "No module named lxml" in e.args or "No module named 'lxml'" in e.args:
HAS_WSDL = False
else:
raise
diff --git a/spyne/interface/_base.py b/spyne/interface/_base.py
index cadc6c5dc..53cf95ad4 100644
--- a/spyne/interface/_base.py
+++ b/spyne/interface/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,40 +17,44 @@
#
import logging
+
logger = logging.getLogger(__name__)
-from collections import deque, defaultdict
+from collections import defaultdict, deque
import spyne.interface
-
-from spyne import EventManager, MethodDescriptor
-from spyne.util import six
-from spyne.model import ModelBase, Array, Iterable, ComplexModelBase
-from spyne.model.complex import XmlModifier
from spyne.const import xml as namespace
+from spyne.descriptor import MethodDescriptor
+from spyne.evmgr import EventManager
+from spyne.model import Array, ComplexModelBase, Iterable, ModelBase
+from spyne.model.complex import XmlModifier
class InterfaceDocumentsBase(object):
- def __init__(self, interface,
- # *, # kwargs start here, commented due to py2 compat
- wsdl11):
+ def __init__(
+ self,
+ interface,
+ # *, # kwargs start here, commented due to py2 compat
+ wsdl11,
+ ):
self.interface = interface
self.wsdl11 = wsdl11
@property
def xml_schema(self):
from spyne.interface import XmlSchema
+
assert isinstance(self.wsdl11, XmlSchema)
return self.wsdl11
class InterfaceDocuments(InterfaceDocumentsBase):
def __init__(self, interface):
- super(InterfaceDocuments, self).__init__(interface,
- wsdl11=None)
+ super(InterfaceDocuments, self).__init__(interface, wsdl11=None)
if spyne.interface.HAS_WSDL:
from spyne.interface.wsdl import Wsdl11
+
self.wsdl11 = Wsdl11(interface)
@@ -62,8 +65,12 @@ class Interface(object):
:param app: A :class:`spyne.application.Application` instance.
"""
- def __init__(self, app=None, import_base_namespaces=False,
- documents_container=InterfaceDocuments):
+ def __init__(
+ self,
+ app=None,
+ import_base_namespaces=False,
+ documents_container=InterfaceDocuments,
+ ):
self.__ns_counter = 0
self.__app = None
self.url = None
@@ -92,8 +99,9 @@ def documents(self, what):
self.docs = what
def set_app(self, value):
- assert self.__app is None, "One interface instance can belong to only " \
- "one application instance."
+ assert self.__app is None, (
+ "One interface instance can belong to only " "one application instance."
+ )
self.__app = value
self.reset_interface()
@@ -119,8 +127,8 @@ def reset_interface(self):
self.prefmap = dict(namespace.PREFMAP)
self.member_methods = deque()
- self.nsmap['tns'] = self.get_tns()
- self.prefmap[self.get_tns()] = 'tns'
+ self.nsmap["tns"] = self.get_tns()
+ self.prefmap[self.get_tns()] = "tns"
self.deps = defaultdict(set)
def has_class(self, cls):
@@ -130,15 +138,14 @@ def has_class(self, cls):
ns = cls.get_namespace()
tn = cls.get_type_name()
- key = '{%s}%s' % (ns, tn)
+ key = "{%s}%s" % (ns, tn)
c = self.classes.get(key)
if c is None:
return False
- if issubclass(c, ComplexModelBase) and \
- issubclass(cls, ComplexModelBase):
- o1 = getattr(cls, '__orig__', None) or cls
- o2 = getattr(c, '__orig__', None) or c
+ if issubclass(c, ComplexModelBase) and issubclass(cls, ComplexModelBase):
+ o1 = getattr(cls, "__orig__", None) or cls
+ o2 = getattr(c, "__orig__", None) or c
if o1 is o2:
return True
@@ -147,8 +154,9 @@ def has_class(self, cls):
if set((o1, o2)) == set((Array, Iterable)):
return True
- raise ValueError("classes %r and %r have conflicting names: '%s'" %
- (cls, c, key))
+ raise ValueError(
+ "classes %r and %r have conflicting names: '%s'" % (cls, c, key)
+ )
return True
def get_class(self, key):
@@ -204,8 +212,9 @@ def add_method(self, method):
if method.aux is None:
yield in_header
in_header_ns = in_header.get_namespace()
- if in_header_ns != self.get_tns() and \
- self.is_valid_import(in_header_ns):
+ if in_header_ns != self.get_tns() and self.is_valid_import(
+ in_header_ns
+ ):
self.imports[self.get_tns()].add(in_header_ns)
if not (method.out_header is None):
@@ -217,8 +226,9 @@ def add_method(self, method):
if method.aux is None:
yield out_header
out_header_ns = out_header.get_namespace()
- if out_header_ns != self.get_tns() and \
- self.is_valid_import(out_header_ns):
+ if out_header_ns != self.get_tns() and self.is_valid_import(
+ out_header_ns
+ ):
self.imports[self.get_tns()].add(out_header_ns)
if method.faults is None:
@@ -234,8 +244,7 @@ def add_method(self, method):
method.in_message.resolve_namespace(method.in_message, self.get_tns())
in_message_ns = method.in_message.get_namespace()
- if in_message_ns != self.get_tns() and \
- self.is_valid_import(in_message_ns):
+ if in_message_ns != self.get_tns() and self.is_valid_import(in_message_ns):
self.imports[self.get_tns()].add(method.in_message.get_namespace())
if method.aux is None:
@@ -245,8 +254,7 @@ def add_method(self, method):
assert not method.out_message.get_type_name() is method.out_message.Empty
out_message_ns = method.out_message.get_namespace()
- if out_message_ns != self.get_tns() and \
- self.is_valid_import(out_message_ns):
+ if out_message_ns != self.get_tns() and self.is_valid_import(out_message_ns):
self.imports[self.get_tns()].add(out_message_ns)
if method.aux is None:
@@ -258,13 +266,16 @@ def add_method(self, method):
def process_method(self, s, method):
assert isinstance(method, MethodDescriptor)
- method_key = u'{%s}%s' % (self.app.tns, method.name)
+ method_key = "{%s}%s" % (self.app.tns, method.name)
if issubclass(s, ComplexModelBase):
- method_object_name = method.name.split('.', 1)[0]
+ method_object_name = method.name.split(".", 1)[0]
if s.get_type_name() != method_object_name:
- method_key = u'{%s}%s.%s' % (self.app.tns, s.get_type_name(),
- method.name)
+ method_key = "{%s}%s.%s" % (
+ self.app.tns,
+ s.get_type_name(),
+ method.name,
+ )
key = method.gen_interface_key(s)
if key in self.method_id_map:
@@ -276,19 +287,34 @@ def process_method(self, s, method):
pass
elif c.__orig__ is None:
- assert c is s.__orig__, "%r.%s conflicts with %r.%s" % \
- (c, key, s.__orig__, key)
+ assert c is s.__orig__, "%r.%s conflicts with %r.%s" % (
+ c,
+ key,
+ s.__orig__,
+ key,
+ )
elif s.__orig__ is None:
- assert c.__orig__ is s, "%r.%s conflicts with %r.%s" % \
- (c.__orig__, key, s, key)
+ assert c.__orig__ is s, "%r.%s conflicts with %r.%s" % (
+ c.__orig__,
+ key,
+ s,
+ key,
+ )
else:
- assert c.__orig__ is s.__orig__, "%r.%s conflicts with %r.%s" % \
- (c.__orig__, key, s.__orig__, key)
+ assert c.__orig__ is s.__orig__, "%r.%s conflicts with %r.%s" % (
+ c.__orig__,
+ key,
+ s.__orig__,
+ key,
+ )
return
- logger.debug(' adding method %s.%s to match %r tag.',
- method.get_owner_name(s), six.get_function_name(method.function),
- method_key)
+ logger.debug(
+ " adding method %s.%s to match %r tag.",
+ method.get_owner_name(s),
+ method.function.__name__,
+ method_key,
+ )
self.method_id_map[key] = method
@@ -310,10 +336,11 @@ def process_method(self, s, method):
os = om.service_class
if os is None:
os = om.parent_class
- raise ValueError("\nThe message %r defined in both '%s.%s'"
- " and '%s.%s'"
- % (method.name, s.__module__, s.__name__,
- os.__module__, os.__name__))
+ raise ValueError(
+ "\nThe message %r defined in both '%s.%s'"
+ " and '%s.%s'"
+ % (method.name, s.__module__, s.__name__, os.__module__, os.__name__)
+ )
def check_method(self, method):
"""Override this if you need to cherry-pick methods added to the
@@ -345,12 +372,12 @@ def populate_interface(self, types=None):
method.aux.methods.append(method.gen_interface_key(s))
if not self.check_method(method):
- logger.debug("method %s' discarded by check_method",
- method.class_key)
+ logger.debug(
+ "method %s' discarded by check_method", method.class_key
+ )
continue
- logger.debug(" enumerating classes for method '%s'",
- method.class_key)
+ logger.debug(" enumerating classes for method '%s'", method.class_key)
for cls in self.add_method(method):
self.add_class(cls)
@@ -360,9 +387,8 @@ def populate_interface(self, types=None):
# populate call routes for service methods
for s in self.services:
- self.service_attrs[s]['tns'] = self.get_tns()
- logger.debug("populating '%s.%s' routes...", s.__module__,
- s.__name__)
+ self.service_attrs[s]["tns"] = self.get_tns()
+ logger.debug("populating '%s.%s' routes...", s.__module__, s.__name__)
for method in s.public_methods.values():
self.process_method(s, method)
@@ -371,8 +397,11 @@ def populate_interface(self, types=None):
should_we = True
if method.static_when is not None:
should_we = method.static_when(self.app)
- logger.debug("static_when returned %r for %s "
- "while populating methods", should_we, method.internal_key)
+ logger.debug(
+ "static_when returned %r for %s " "while populating methods",
+ should_we,
+ method.internal_key,
+ )
if should_we:
s = method.service_class
@@ -390,12 +419,15 @@ def populate_interface(self, types=None):
self.process_method(cls.__orig__ or cls, method)
# populate method descriptor id to method key map
- self.method_descriptor_id_to_key = dict(((id(v[0]), k)
- for k,v in self.service_method_map.items()))
+ self.method_descriptor_id_to_key = dict(
+ ((id(v[0]), k) for k, v in self.service_method_map.items())
+ )
- logger.debug("From this point on, you're not supposed to make any "
- "changes to the class and method structure of the exposed "
- "services.")
+ logger.debug(
+ "From this point on, you're not supposed to make any "
+ "changes to the class and method structure of the exposed "
+ "services."
+ )
tns = property(get_tns)
@@ -406,7 +438,7 @@ def get_namespace_prefix(self, ns):
Not meant to be overridden.
"""
- if not (isinstance(ns, str) or isinstance(ns, six.text_type)):
+ if not isinstance(ns, str):
raise TypeError(ns)
if not (ns in self.prefmap):
@@ -432,18 +464,24 @@ def add_class(self, cls, add_parent=True):
ns = cls.get_namespace()
tn = cls.get_type_name()
- assert ns is not None, ('either assign a namespace to the class or call'
- ' cls.resolve_namespace(cls, "some_default_ns") on it.')
+ assert ns is not None, (
+ "either assign a namespace to the class or call"
+ ' cls.resolve_namespace(cls, "some_default_ns") on it.'
+ )
if not (ns in self.imports) and self.is_valid_import(ns):
self.imports[ns] = set()
- class_key = '{%s}%s' % (ns, tn)
- logger.debug(' adding class %r for %r', repr(cls), class_key)
+ class_key = "{%s}%s" % (ns, tn)
+ logger.debug(" adding class %r for %r", repr(cls), class_key)
- assert class_key not in self.classes, ("Somehow, you're trying to "
- "overwrite %r by %r for class key %r." %
- (self.classes[class_key], cls, class_key))
+ assert (
+ class_key not in self.classes
+ ), "Somehow, you're trying to " "overwrite %r by %r for class key %r." % (
+ self.classes[class_key],
+ cls,
+ class_key,
+ )
assert not (cls.get_type_name() is cls.Empty), cls
@@ -453,22 +491,28 @@ def add_class(self, cls, add_parent=True):
self.classes[tn] = cls
# add parent class
- extends = getattr(cls, '__extends__', None)
- while extends is not None and \
- (extends.get_type_name() is ModelBase.Empty):
- extends = getattr(extends, '__extends__', None)
+ extends = getattr(cls, "__extends__", None)
+ while extends is not None and (extends.get_type_name() is ModelBase.Empty):
+ extends = getattr(extends, "__extends__", None)
if add_parent and extends is not None:
assert issubclass(extends, ModelBase)
self.deps[cls].add(extends)
self.add_class(extends)
parent_ns = extends.get_namespace()
- if parent_ns != ns and not parent_ns in self.imports[ns] and \
- self.is_valid_import(parent_ns):
+ if (
+ parent_ns != ns
+ and not parent_ns in self.imports[ns]
+ and self.is_valid_import(parent_ns)
+ ):
self.imports[ns].add(parent_ns)
- logger.debug(" importing %r to %r because %r extends %r",
- parent_ns, ns, cls.get_type_name(),
- extends.get_type_name())
+ logger.debug(
+ " importing %r to %r because %r extends %r",
+ parent_ns,
+ ns,
+ cls.get_type_name(),
+ extends.get_type_name(),
+ )
# add fields
if issubclass(cls, ComplexModelBase):
@@ -488,25 +532,46 @@ def add_class(self, cls, add_parent=True):
v.resolve_namespace(v, cls.get_namespace())
child_ns = v.get_namespace()
- if child_ns != ns and not child_ns in self.imports[ns] and \
- self.is_valid_import(child_ns):
+ if (
+ child_ns != ns
+ and not child_ns in self.imports[ns]
+ and self.is_valid_import(child_ns)
+ ):
self.imports[ns].add(child_ns)
- logger.debug(" importing %r to %r for %s.%s(%r)",
- child_ns, ns, cls.get_type_name(), k, v)
+ logger.debug(
+ " importing %r to %r for %s.%s(%r)",
+ child_ns,
+ ns,
+ cls.get_type_name(),
+ k,
+ v,
+ )
if issubclass(v, XmlModifier):
self.add_class(v.type)
child_ns = v.type.get_namespace()
- if child_ns != ns and not child_ns in self.imports[ns] and \
- self.is_valid_import(child_ns):
+ if (
+ child_ns != ns
+ and not child_ns in self.imports[ns]
+ and self.is_valid_import(child_ns)
+ ):
self.imports[ns].add(child_ns)
- logger.debug(" importing %r to %r for %s.%s(%r)",
- child_ns, ns, v.get_type_name(), k, v.type)
+ logger.debug(
+ " importing %r to %r for %s.%s(%r)",
+ child_ns,
+ ns,
+ v.get_type_name(),
+ k,
+ v.type,
+ )
if cls.Attributes.methods is not None:
- logger.debug(" populating member methods for '%s.%s'...",
- cls.get_namespace(), cls.get_type_name())
+ logger.debug(
+ " populating member methods for '%s.%s'...",
+ cls.get_namespace(),
+ cls.get_type_name(),
+ )
for method_key, descriptor in cls.Attributes.methods.items():
assert hasattr(cls, method_key)
@@ -514,9 +579,12 @@ def add_class(self, cls, add_parent=True):
should_we = True
if descriptor.static_when is not None:
should_we = descriptor.static_when(self.app)
- logger.debug("static_when returned %r for %s "
+ logger.debug(
+ "static_when returned %r for %s "
"while populating classes",
- should_we, descriptor.internal_key)
+ should_we,
+ descriptor.internal_key,
+ )
if should_we:
self.member_methods.append((cls, descriptor))
@@ -524,8 +592,11 @@ def add_class(self, cls, add_parent=True):
self.add_class(c)
if cls.Attributes._subclasses is not None:
- logger.debug(" adding subclasses of '%s.%s'...",
- cls.get_namespace(), cls.get_type_name())
+ logger.debug(
+ " adding subclasses of '%s.%s'...",
+ cls.get_namespace(),
+ cls.get_type_name(),
+ )
for c in cls.Attributes._subclasses:
c.resolve_namespace(c, ns)
@@ -536,10 +607,15 @@ def add_class(self, cls, add_parent=True):
self.add_class(c, add_parent=False)
self.deps[c].add(cls)
else:
- logger.debug(" not adding %r to %r because it would "
+ logger.debug(
+ " not adding %r to %r because it would "
"cause circular imports because %r extends %r and "
- "they don't have the same namespace", child_ns,
- ns, c.get_type_name(), cls.get_type_name())
+ "they don't have the same namespace",
+ child_ns,
+ ns,
+ c.get_type_name(),
+ cls.get_type_name(),
+ )
def is_valid_import(self, ns):
"""This will return False for base namespaces unless told otherwise."""
@@ -567,7 +643,7 @@ def build_interface_document(self):
function as this may result in the same event firing more than once.
"""
- raise NotImplementedError('Extend and override.')
+ raise NotImplementedError("Extend and override.")
def get_interface_document(self):
"""This function is called by server transports that try to satisfy the
@@ -575,4 +651,4 @@ def get_interface_document(self):
cached interface document.
"""
- raise NotImplementedError('Extend and override.')
+ raise NotImplementedError("Extend and override.")
diff --git a/spyne/interface/wsdl/__init__.py b/spyne/interface/wsdl/__init__.py
index c7868e5c9..ec1b82a0f 100644
--- a/spyne/interface/wsdl/__init__.py
+++ b/spyne/interface/wsdl/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
diff --git a/spyne/interface/wsdl/defn.py b/spyne/interface/wsdl/defn.py
index e072b283f..7b0484321 100644
--- a/spyne/interface/wsdl/defn.py
+++ b/spyne/interface/wsdl/defn.py
@@ -1,22 +1,14 @@
-
-from spyne.util.six import add_metaclass
-
from spyne.const import xml
-
+from spyne.interface.xml_schema.defn import XmlSchema10
+from spyne.model.complex import ComplexModelBase, ComplexModelMeta, XmlAttribute
from spyne.model.primitive import Unicode
-from spyne.model.complex import XmlAttribute
-from spyne.model.complex import ComplexModelBase
-from spyne.model.complex import ComplexModelMeta
-from spyne.interface.xml_schema.defn import XmlSchema10
-@add_metaclass(ComplexModelMeta)
-class Wsdl11Base(ComplexModelBase):
+class Wsdl11Base(ComplexModelBase, metaclass=ComplexModelMeta):
__namespace__ = xml.NS_WSDL11
-@add_metaclass(ComplexModelMeta)
-class Soap11Base(ComplexModelBase):
+class Soap11Base(ComplexModelBase, metaclass=ComplexModelMeta):
__namespace__ = xml.NS_WSDL11_SOAP
@@ -47,10 +39,10 @@ class SoapHeaderDefinition(Wsdl11Base):
class OperationMode(Wsdl11Base):
name = XmlAttribute(Unicode)
message = XmlAttribute(Unicode)
- soap_body = SoapBodyDefinition.customize(sub_ns=xml.NS_WSDL11_SOAP,
- sub_name="body")
- soap_header = SoapHeaderDefinition.customize(sub_ns=xml.NS_WSDL11_SOAP,
- sub_name="header")
+ soap_body = SoapBodyDefinition.customize(sub_ns=xml.NS_WSDL11_SOAP, sub_name="body")
+ soap_header = SoapHeaderDefinition.customize(
+ sub_ns=xml.NS_WSDL11_SOAP, sub_name="header"
+ )
class SoapOperation(Wsdl11Base):
@@ -61,10 +53,12 @@ class SoapOperation(Wsdl11Base):
class Operation(Wsdl11Base):
input = OperationMode
output = OperationMode
- soap_operation = SoapOperation.customize(sub_ns=xml.NS_WSDL11_SOAP,
- sub_name="operation")
+ soap_operation = SoapOperation.customize(
+ sub_ns=xml.NS_WSDL11_SOAP, sub_name="operation"
+ )
parameterOrder = XmlAttribute(Unicode)
+
class PortType(Wsdl11Base):
name = XmlAttribute(Unicode)
operation = Operation.customize(max_occurs="unbounded")
@@ -79,8 +73,7 @@ class Binding(Wsdl11Base):
name = XmlAttribute(Unicode)
type = XmlAttribute(Unicode)
location = XmlAttribute(Unicode)
- soap_binding = SoapBinding.customize(sub_ns=xml.NS_WSDL11_SOAP,
- sub_name="binding")
+ soap_binding = SoapBinding.customize(sub_ns=xml.NS_WSDL11_SOAP, sub_name="binding")
class PortAddress(Soap11Base):
@@ -100,9 +93,9 @@ class Service(Wsdl11Base):
class Wsdl11(Wsdl11Base):
_type_info = [
- ('types', Types),
- ('message', Message.customize(max_occurs="unbounded")),
- ('service', Service),
- ('portType', PortType),
- ('binding', Binding),
+ ("types", Types),
+ ("message", Message.customize(max_occurs="unbounded")),
+ ("service", Service),
+ ("portType", PortType),
+ ("binding", Binding),
]
diff --git a/spyne/interface/wsdl/wsdl11.py b/spyne/interface/wsdl/wsdl11.py
index 71a430dfe..ddba0c43d 100644
--- a/spyne/interface/wsdl/wsdl11.py
+++ b/spyne/interface/wsdl/wsdl11.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -22,26 +21,24 @@
"""
import logging
+
logger = logging.getLogger(__name__)
import re
-import spyne.const.xml as ns
-
-from spyne.util import six
-
from lxml import etree
from lxml.builder import E
from lxml.etree import SubElement
-from spyne.const.xml import WSDL11, XSD, NS_WSA, PLINK
+import spyne.const.xml as ns
+from spyne.const.xml import NS_WSA, PLINK, WSDL11, XSD
from spyne.interface.xml_schema import XmlSchema
-REGEX_WSDL = re.compile('[.?]wsdl$')
+REGEX_WSDL = re.compile("[.?]wsdl$")
PREF_WSA = ns.PREFMAP[NS_WSA]
-_in_header_msg_suffix = 'InHeaderMsg'
-_out_header_msg_suffix = 'OutHeaderMsg'
+_in_header_msg_suffix = "InHeaderMsg"
+_out_header_msg_suffix = "OutHeaderMsg"
def check_method_port(service, method):
@@ -60,7 +57,7 @@ class declares a list of ports
or add a list of ports to the service class
""")
try:
- if (not method.port_type is None):
+ if not method.port_type is None:
index = service.__port_types__.index(method.port_type)
except ValueError as e:
@@ -92,10 +89,16 @@ class Wsdl11(XmlSchema):
#:param import_base_namespaces: Include imports for base namespaces like
# xsd, xsi, wsdl, etc.
- def __init__(self, interface=None, xsl_href=None, _with_partnerlink=False,
- element_form_default='qualified'):
+ def __init__(
+ self,
+ interface=None,
+ xsl_href=None,
+ _with_partnerlink=False,
+ element_form_default="qualified",
+ ):
super(Wsdl11, self).__init__(
- interface, element_form_default=element_form_default)
+ interface, element_form_default=element_form_default
+ )
self._with_plink = _with_partnerlink
self.xsl_href = xsl_href
@@ -110,7 +113,7 @@ def __init__(self, interface=None, xsl_href=None, _with_partnerlink=False,
self.validation_schema = None
def _get_binding_name(self, port_type_name):
- return port_type_name # subclasses override to control port names.
+ return port_type_name # subclasses override to control port names.
def _get_or_create_port_type(self, pt_name):
"""Creates a wsdl:portType element."""
@@ -119,7 +122,7 @@ def _get_or_create_port_type(self, pt_name):
if not pt_name in self.port_type_dict:
pt = SubElement(self.root_elt, WSDL11("portType"))
- pt.set('name', pt_name)
+ pt.set("name", pt_name)
self.port_type_dict[pt_name] = pt
else:
@@ -133,7 +136,7 @@ def _get_or_create_service_node(self, service_name):
ser = None
if not service_name in self.service_elt_dict:
ser = SubElement(self.root_elt, WSDL11("service"))
- ser.set('name', service_name)
+ ser.set("name", service_name)
self.service_elt_dict[service_name] = ser
else:
@@ -149,30 +152,32 @@ def build_interface_document(self, url):
self.build_schema_nodes()
- self.url = REGEX_WSDL.sub('', url)
+ self.url = REGEX_WSDL.sub("", url)
service_name = self.interface.get_name()
# create wsdl root node
- self.root_elt = root = etree.Element(WSDL11("definitions"),
- nsmap=self.interface.nsmap)
+ self.root_elt = root = etree.Element(
+ WSDL11("definitions"), nsmap=self.interface.nsmap
+ )
if self.xsl_href is not None:
# example:
# "
# pi.attrib.__setitem__ is ignored, so we get a proper list of
# attributes to pass with the following hack.
- pitext = etree.tostring(etree.Element("dummy",
- dict(type='text/xsl', href=self.xsl_href)), encoding='unicode') \
- .split(" ", 1)[-1][:-2]
+ pitext = etree.tostring(
+ etree.Element("dummy", dict(type="text/xsl", href=self.xsl_href)),
+ encoding="unicode",
+ ).split(" ", 1)[-1][:-2]
pi = etree.ProcessingInstruction("xml-stylesheet", pitext)
self.root_elt.addprevious(pi)
self.root_tree = root.getroottree()
- root.set('targetNamespace', self.interface.tns)
- root.set('name', service_name)
+ root.set("targetNamespace", self.interface.tns)
+ root.set("name", service_name)
# create types node
types = SubElement(root, WSDL11("types"))
@@ -185,7 +190,7 @@ def build_interface_document(self, url):
if self._with_plink:
plink = SubElement(root, PLINK("partnerLinkType"))
- plink.set('name', service_name)
+ plink.set("name", service_name)
self.__add_partner_link(service_name, plink)
# create service nodes in advance. they're to be filled in subsequent
@@ -202,18 +207,22 @@ def build_interface_document(self, url):
cb_binding = None
for s in self.interface.services:
if not s.is_auxiliary():
- cb_binding = self.add_bindings_for_methods(s, root,
- service_name, cb_binding)
+ cb_binding = self.add_bindings_for_methods(
+ s, root, service_name, cb_binding
+ )
if self.interface.app.transport is None:
- raise Exception("You must set the 'transport' property of the "
- "parent 'Application' instance")
+ raise Exception(
+ "You must set the 'transport' property of the "
+ "parent 'Application' instance"
+ )
- self.event_manager.fire_event('document_built', self)
- self.event_manager.fire_event('wsdl_document_built', self)
+ self.event_manager.fire_event("document_built", self)
+ self.event_manager.fire_event("wsdl_document_built", self)
- self.__wsdl = etree.tostring(self.root_tree, xml_declaration=True,
- encoding="UTF-8")
+ self.__wsdl = etree.tostring(
+ self.root_tree, xml_declaration=True, encoding="UTF-8"
+ )
def __add_partner_link(self, service_name, plink):
"""Add the partnerLinkType node to the wsdl."""
@@ -222,32 +231,32 @@ def __add_partner_link(self, service_name, plink):
pref_tns = self.interface.get_namespace_prefix(ns_tns)
role = SubElement(plink, PLINK("role"))
- role.set('name', service_name)
+ role.set("name", service_name)
plink_port_type = SubElement(role, PLINK("portType"))
- plink_port_type.set('name', '%s:%s' % (pref_tns, service_name))
+ plink_port_type.set("name", "%s:%s" % (pref_tns, service_name))
if self._has_callbacks():
role = SubElement(plink, PLINK("role"))
- role.set('name', '%sCallback' % service_name)
+ role.set("name", "%sCallback" % service_name)
plink_port_type = SubElement(role, PLINK("portType"))
- plink_port_type.set('name', '%s:%sCallback' %
- (pref_tns, service_name))
+ plink_port_type.set("name", "%s:%sCallback" % (pref_tns, service_name))
def _add_port_to_service(self, service, port_name, binding_name):
- """ Builds a wsdl:port for a service and binding"""
+ """Builds a wsdl:port for a service and binding"""
pref_tns = self.interface.get_namespace_prefix(self.interface.tns)
wsdl_port = SubElement(service, WSDL11("port"))
- wsdl_port.set('name', port_name)
- wsdl_port.set('binding', '%s:%s' % (pref_tns, binding_name))
+ wsdl_port.set("name", port_name)
+ wsdl_port.set("binding", "%s:%s" % (pref_tns, binding_name))
- addr = SubElement(wsdl_port,
- ns.get_binding_ns(self.interface.app.in_protocol.type)("address"))
+ addr = SubElement(
+ wsdl_port, ns.get_binding_ns(self.interface.app.in_protocol.type)("address")
+ )
- addr.set('location', self.url)
+ addr.set("location", self.url)
def _has_callbacks(self):
for s in self.interface.services:
@@ -271,8 +280,7 @@ def _get_applied_service_name(self, service):
def add_port_type(self, service, root, service_name, types, url):
# FIXME: I don't think this call is working.
- cb_port_type = self._add_callbacks(service, root, types,
- service_name, url)
+ cb_port_type = self._add_callbacks(service, root, types, service_name, url)
applied_service_name = self._get_applied_service_name(service)
port_binding_names = []
@@ -280,14 +288,14 @@ def add_port_type(self, service, root, service_name, types, url):
if len(port_type_list) > 0:
for port_type_name in port_type_list:
port_type = self._get_or_create_port_type(port_type_name)
- port_type.set('name', port_type_name)
+ port_type.set("name", port_type_name)
binding_name = self._get_binding_name(port_type_name)
port_binding_names.append((port_type_name, binding_name))
else:
port_type = self._get_or_create_port_type(service_name)
- port_type.set('name', service_name)
+ port_type.set("name", service_name)
binding_name = self._get_binding_name(service_name)
port_binding_names.append((service_name, binding_name))
@@ -300,31 +308,38 @@ def add_port_type(self, service, root, service_name, types, url):
else:
operation = SubElement(port_type, WSDL11("operation"))
- operation.set('name', method.operation_name)
+ operation.set("name", method.operation_name)
if method.doc is not None:
operation.append(E(WSDL11("documentation"), method.doc))
- operation.set('parameterOrder', method.in_message.get_element_name())
+ operation.set("parameterOrder", method.in_message.get_element_name())
op_input = SubElement(operation, WSDL11("input"))
- op_input.set('name', method.in_message.get_element_name())
- op_input.set('message',
- method.in_message.get_element_name_ns(self.interface))
+ op_input.set("name", method.in_message.get_element_name())
+ op_input.set(
+ "message", method.in_message.get_element_name_ns(self.interface)
+ )
if (not method.is_callback) and (not method.is_async):
op_output = SubElement(operation, WSDL11("output"))
- op_output.set('name', method.out_message.get_element_name())
- op_output.set('message', method.out_message.get_element_name_ns(
- self.interface))
+ op_output.set("name", method.out_message.get_element_name())
+ op_output.set(
+ "message", method.out_message.get_element_name_ns(self.interface)
+ )
if not (method.faults is None):
for f in method.faults:
fault = SubElement(operation, WSDL11("fault"))
- fault.set('name', f.get_type_name())
- fault.set('message', '%s:%s' % (
- f.get_namespace_prefix(self.interface),
- f.get_type_name()))
+ fault.set("name", f.get_type_name())
+ fault.set(
+ "message",
+ "%s:%s"
+ % (
+ f.get_namespace_prefix(self.interface),
+ f.get_type_name(),
+ ),
+ )
ser = self.service_elt_dict[applied_service_name]
for port_name, binding_name in port_binding_names:
@@ -335,7 +350,7 @@ def _add_message_for_object(self, root, messages, obj, message_name):
messages.add(message_name)
message = SubElement(root, WSDL11("message"))
- message.set('name', message_name)
+ message.set("name", message_name)
if isinstance(obj, (list, tuple)):
objs = obj
@@ -344,40 +359,59 @@ def _add_message_for_object(self, root, messages, obj, message_name):
for obj in objs:
part = SubElement(message, WSDL11("part"))
- part.set('name', obj.get_wsdl_part_name())
- part.set('element', obj.get_element_name_ns(self.interface))
+ part.set("name", obj.get_wsdl_part_name())
+ part.set("element", obj.get_element_name_ns(self.interface))
def add_messages_for_methods(self, service, root, messages):
for method in service.public_methods.values():
- self._add_message_for_object(root, messages, method.in_message,
- method.in_message.get_element_name())
- self._add_message_for_object(root, messages, method.out_message,
- method.out_message.get_element_name())
-
- if method.in_header is not None:
- if len(method.in_header) > 1:
- in_header_message_name = ''.join((method.name,
- _in_header_msg_suffix))
+ self._add_message_for_object(
+ root, messages, method.in_message, method.in_message.get_element_name()
+ )
+ self._add_message_for_object(
+ root,
+ messages,
+ method.out_message,
+ method.out_message.get_element_name(),
+ )
+
+ in_header = method.in_header
+ if in_header is None and service.__in_header__ is not None:
+ svc_hdr = service.__in_header__
+ in_header = svc_hdr if isinstance(svc_hdr, tuple) else (svc_hdr,)
+
+ if in_header is not None:
+ if len(in_header) > 1:
+ in_header_message_name = "".join(
+ (method.name, _in_header_msg_suffix)
+ )
else:
- in_header_message_name = method.in_header[0].get_type_name()
- self._add_message_for_object(root, messages,
- method.in_header, in_header_message_name)
-
- if method.out_header is not None:
- if len(method.out_header) > 1:
- out_header_message_name = ''.join((method.name,
- _out_header_msg_suffix))
+ in_header_message_name = in_header[0].get_type_name()
+ self._add_message_for_object(
+ root, messages, in_header, in_header_message_name
+ )
+
+ out_header = method.out_header
+ if out_header is None and service.__out_header__ is not None:
+ svc_hdr = service.__out_header__
+ out_header = svc_hdr if isinstance(svc_hdr, tuple) else (svc_hdr,)
+
+ if out_header is not None:
+ if len(out_header) > 1:
+ out_header_message_name = "".join(
+ (method.name, _out_header_msg_suffix)
+ )
else:
- out_header_message_name = method.out_header[0].get_type_name()
- self._add_message_for_object(root, messages,
- method.out_header, out_header_message_name)
+ out_header_message_name = out_header[0].get_type_name()
+ self._add_message_for_object(
+ root, messages, out_header, out_header_message_name
+ )
for fault in method.faults:
- self._add_message_for_object(root, messages, fault,
- fault.get_type_name())
+ self._add_message_for_object(
+ root, messages, fault, fault.get_type_name()
+ )
- def add_bindings_for_methods(self, service, root, service_name,
- cb_binding):
+ def add_bindings_for_methods(self, service, root, service_name, cb_binding):
pref_tns = self.interface.get_namespace_prefix(self.interface.get_tns())
input_binding_ns = ns.get_binding_ns(self.interface.app.in_protocol.type)
@@ -385,18 +419,18 @@ def add_bindings_for_methods(self, service, root, service_name,
def inner(method, binding):
operation = etree.Element(WSDL11("operation"))
- operation.set('name', method.operation_name)
+ operation.set("name", method.operation_name)
soap_operation = SubElement(operation, input_binding_ns("operation"))
- soap_operation.set('soapAction', method.operation_name)
- soap_operation.set('style', 'document')
+ soap_operation.set("soapAction", method.operation_name)
+ soap_operation.set("style", "document")
# get input
input = SubElement(operation, WSDL11("input"))
- input.set('name', method.in_message.get_element_name())
+ input.set("name", method.in_message.get_element_name())
soap_body = SubElement(input, input_binding_ns("body"))
- soap_body.set('use', 'literal')
+ soap_body.set("use", "literal")
# get input soap header
in_header = method.in_header
@@ -410,25 +444,31 @@ def inner(method, binding):
in_headers = (in_header,)
if len(in_headers) > 1:
- in_header_message_name = ''.join((method.name,
- _in_header_msg_suffix))
+ in_header_message_name = "".join(
+ (method.name, _in_header_msg_suffix)
+ )
else:
in_header_message_name = in_headers[0].get_type_name()
for header in in_headers:
- soap_header = SubElement(input, input_binding_ns('header'))
- soap_header.set('use', 'literal')
- soap_header.set('message', '%s:%s' % (
- header.get_namespace_prefix(self.interface),
- in_header_message_name))
- soap_header.set('part', header.get_type_name())
+ soap_header = SubElement(input, input_binding_ns("header"))
+ soap_header.set("use", "literal")
+ soap_header.set(
+ "message",
+ "%s:%s"
+ % (
+ header.get_namespace_prefix(self.interface),
+ in_header_message_name,
+ ),
+ )
+ soap_header.set("part", header.get_type_name())
if not (method.is_async or method.is_callback):
output = SubElement(operation, WSDL11("output"))
- output.set('name', method.out_message.get_element_name())
+ output.set("name", method.out_message.get_element_name())
soap_body = SubElement(output, output_binding_ns("body"))
- soap_body.set('use', 'literal')
+ soap_body.set("use", "literal")
# get output soap header
out_header = method.out_header
@@ -442,48 +482,54 @@ def inner(method, binding):
out_headers = (out_header,)
if len(out_headers) > 1:
- out_header_message_name = ''.join((method.name,
- _out_header_msg_suffix))
+ out_header_message_name = "".join(
+ (method.name, _out_header_msg_suffix)
+ )
else:
out_header_message_name = out_headers[0].get_type_name()
for header in out_headers:
soap_header = SubElement(output, output_binding_ns("header"))
- soap_header.set('use', 'literal')
- soap_header.set('message', '%s:%s' % (
+ soap_header.set("use", "literal")
+ soap_header.set(
+ "message",
+ "%s:%s"
+ % (
header.get_namespace_prefix(self.interface),
- out_header_message_name))
- soap_header.set('part', header.get_type_name())
+ out_header_message_name,
+ ),
+ )
+ soap_header.set("part", header.get_type_name())
if not (method.faults is None):
for f in method.faults:
wsdl_fault = SubElement(operation, WSDL11("fault"))
- wsdl_fault.set('name', f.get_type_name())
+ wsdl_fault.set("name", f.get_type_name())
soap_fault = SubElement(wsdl_fault, input_binding_ns("fault"))
- soap_fault.set('name', f.get_type_name())
- soap_fault.set('use', 'literal')
+ soap_fault.set("name", f.get_type_name())
+ soap_fault.set("use", "literal")
if method.is_callback:
relates_to = SubElement(input, input_binding_ns("header"))
- relates_to.set('message', '%s:RelatesToHeader' % pref_tns)
- relates_to.set('part', 'RelatesTo')
- relates_to.set('use', 'literal')
+ relates_to.set("message", "%s:RelatesToHeader" % pref_tns)
+ relates_to.set("part", "RelatesTo")
+ relates_to.set("use", "literal")
cb_binding.append(operation)
else:
if method.is_async:
rt_header = SubElement(input, input_binding_ns("header"))
- rt_header.set('message', '%s:ReplyToHeader' % pref_tns)
- rt_header.set('part', 'ReplyTo')
- rt_header.set('use', 'literal')
+ rt_header.set("message", "%s:ReplyToHeader" % pref_tns)
+ rt_header.set("part", "ReplyTo")
+ rt_header.set("use", "literal")
mid_header = SubElement(input, input_binding_ns("header"))
- mid_header.set('message', '%s:MessageIDHeader' % pref_tns)
- mid_header.set('part', 'MessageID')
- mid_header.set('use', 'literal')
+ mid_header.set("message", "%s:MessageIDHeader" % pref_tns)
+ mid_header.set("part", "MessageID")
+ mid_header.set("use", "literal")
binding.append(operation)
@@ -493,12 +539,12 @@ def inner(method, binding):
# create binding nodes
binding = SubElement(root, WSDL11("binding"))
- binding.set('name', self._get_binding_name(port_type_name))
- binding.set('type', '%s:%s'% (pref_tns, port_type_name))
+ binding.set("name", self._get_binding_name(port_type_name))
+ binding.set("type", "%s:%s" % (pref_tns, port_type_name))
transport = SubElement(binding, input_binding_ns("binding"))
- transport.set('style', 'document')
- transport.set('transport', self.interface.app.transport)
+ transport.set("style", "document")
+ transport.set("transport", self.interface.app.transport)
for m in service.public_methods.values():
if m.port_type == port_type_name:
@@ -508,12 +554,12 @@ def inner(method, binding):
# here is the default port.
if cb_binding is None:
cb_binding = SubElement(root, WSDL11("binding"))
- cb_binding.set('name', service_name)
- cb_binding.set('type', '%s:%s'% (pref_tns, service_name))
+ cb_binding.set("name", service_name)
+ cb_binding.set("type", "%s:%s" % (pref_tns, service_name))
transport = SubElement(cb_binding, input_binding_ns("binding"))
- transport.set('style', 'document')
- transport.set('transport', self.interface.app.transport)
+ transport.set("style", "document")
+ transport.set("transport", self.interface.app.transport)
for m in service.public_methods.values():
inner(m, cb_binding)
@@ -523,7 +569,7 @@ def inner(method, binding):
# FIXME: I don't think this is working.
def _add_callbacks(self, service, root, types, service_name, url):
ns_tns = self.interface.get_tns()
- pref_tns = 'tns'
+ pref_tns = "tns"
input_binding_ns = ns.get_binding_ns(self.interface.app.in_protocol.type)
cb_port_type = None
@@ -533,7 +579,7 @@ def _add_callbacks(self, service, root, types, service_name, url):
# callback porttype
if service._has_callbacks():
wsa_schema = SubElement(types, XSD("schema"))
- wsa_schema.set("targetNamespace", '%sCallback' % ns_tns)
+ wsa_schema.set("targetNamespace", "%sCallback" % ns_tns)
wsa_schema.set("elementFormDefault", "qualified")
import_ = SubElement(wsa_schema, XSD("import"))
@@ -541,37 +587,37 @@ def _add_callbacks(self, service, root, types, service_name, url):
import_.set("schemaLocation", NS_WSA)
relt_message = SubElement(root, WSDL11("message"))
- relt_message.set('name', 'RelatesToHeader')
+ relt_message.set("name", "RelatesToHeader")
relt_part = SubElement(relt_message, WSDL11("part"))
- relt_part.set('name', 'RelatesTo')
- relt_part.set('element', '%s:RelatesTo' % PREF_WSA)
+ relt_part.set("name", "RelatesTo")
+ relt_part.set("element", "%s:RelatesTo" % PREF_WSA)
reply_message = SubElement(root, WSDL11("message"))
- reply_message.set('name', 'ReplyToHeader')
+ reply_message.set("name", "ReplyToHeader")
reply_part = SubElement(reply_message, WSDL11("part"))
- reply_part.set('name', 'ReplyTo')
- reply_part.set('element', '%s:ReplyTo' % PREF_WSA)
+ reply_part.set("name", "ReplyTo")
+ reply_part.set("element", "%s:ReplyTo" % PREF_WSA)
id_header = SubElement(root, WSDL11("message"))
- id_header.set('name', 'MessageIDHeader')
+ id_header.set("name", "MessageIDHeader")
id_part = SubElement(id_header, WSDL11("part"))
- id_part.set('name', 'MessageID')
- id_part.set('element', '%s:MessageID' % PREF_WSA)
+ id_part.set("name", "MessageID")
+ id_part.set("element", "%s:MessageID" % PREF_WSA)
# make portTypes
cb_port_type = SubElement(root, WSDL11("portType"))
- cb_port_type.set('name', '%sCallback' % service_name)
+ cb_port_type.set("name", "%sCallback" % service_name)
- cb_service_name = '%sCallback' % service_name
+ cb_service_name = "%sCallback" % service_name
cb_service = SubElement(root, WSDL11("service"))
- cb_service.set('name', cb_service_name)
+ cb_service.set("name", cb_service_name)
cb_wsdl_port = SubElement(cb_service, WSDL11("port"))
- cb_wsdl_port.set('name', cb_service_name)
- cb_wsdl_port.set('binding', '%s:%s' % (pref_tns, cb_service_name))
+ cb_wsdl_port.set("name", cb_service_name)
+ cb_wsdl_port.set("binding", "%s:%s" % (pref_tns, cb_service_name))
cb_address = SubElement(cb_wsdl_port, input_binding_ns("address"))
- cb_address.set('location', url)
+ cb_address.set("location", url)
return cb_port_type
diff --git a/spyne/interface/xml_schema/__init__.py b/spyne/interface/xml_schema/__init__.py
index 3e157f54c..7ea7a3e2d 100644
--- a/spyne/interface/xml_schema/__init__.py
+++ b/spyne/interface/xml_schema/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
diff --git a/spyne/interface/xml_schema/_base.py b/spyne/interface/xml_schema/_base.py
index 4c45a85af..178283d4a 100644
--- a/spyne/interface/xml_schema/_base.py
+++ b/spyne/interface/xml_schema/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,55 +17,66 @@
#
import logging
-logger = logging.getLogger('.'.join(__name__.split(".")[:-1]))
+
+logger = logging.getLogger(".".join(__name__.split(".")[:-1]))
import os
import shutil
import tempfile
-
-import spyne.const.xml as ns
+from itertools import chain
from lxml import etree
-from itertools import chain
+import spyne.const.xml as ns
+from spyne.interface import InterfaceDocumentBase
+from spyne.interface.xml_schema.model import (
+ Tget_range_restriction_tag,
+ byte_array_add,
+ complex_add,
+ enum_add,
+ fault_add,
+ simple_add,
+ simple_get_restriction_tag,
+ unicode_get_restriction_tag,
+)
+from spyne.model import (
+ ByteArray,
+ ComplexModelBase,
+ Date,
+ DateTime,
+ Decimal,
+ Fault,
+ SimpleModel,
+ Time,
+ Unicode,
+)
+from spyne.model.enum import EnumBase
from spyne.util.cdict import cdict
from spyne.util.odict import odict
from spyne.util.toposort import toposort2
-from spyne.model import SimpleModel, ByteArray, ComplexModelBase, Fault, \
- Decimal, DateTime, Date, Time, Unicode
-from spyne.model.enum import EnumBase
-from spyne.interface import InterfaceDocumentBase
-
-from spyne.interface.xml_schema.model import byte_array_add
-from spyne.interface.xml_schema.model import simple_add
-from spyne.interface.xml_schema.model import complex_add
-from spyne.interface.xml_schema.model import fault_add
-from spyne.interface.xml_schema.model import enum_add
-
-from spyne.interface.xml_schema.model import simple_get_restriction_tag
-from spyne.interface.xml_schema.model import unicode_get_restriction_tag
-from spyne.interface.xml_schema.model import Tget_range_restriction_tag
-
-
-_add_handlers = cdict({
- object: lambda interface, cls, tags: None,
- ByteArray: byte_array_add,
- SimpleModel: simple_add,
- ComplexModelBase: complex_add,
- Fault: fault_add,
- EnumBase: enum_add,
-})
-
-_get_restriction_tag_handlers = cdict({
- object: lambda self, cls: None,
- SimpleModel: simple_get_restriction_tag,
- Unicode: unicode_get_restriction_tag,
- Decimal: Tget_range_restriction_tag(Decimal),
- DateTime: Tget_range_restriction_tag(DateTime),
- Time: Tget_range_restriction_tag(Time),
- Date: Tget_range_restriction_tag(Date),
-})
+_add_handlers = cdict(
+ {
+ object: lambda interface, cls, tags: None,
+ ByteArray: byte_array_add,
+ SimpleModel: simple_add,
+ ComplexModelBase: complex_add,
+ Fault: fault_add,
+ EnumBase: enum_add,
+ }
+)
+
+_get_restriction_tag_handlers = cdict(
+ {
+ object: lambda self, cls: None,
+ SimpleModel: simple_get_restriction_tag,
+ Unicode: unicode_get_restriction_tag,
+ Decimal: Tget_range_restriction_tag(Decimal),
+ DateTime: Tget_range_restriction_tag(DateTime),
+ Time: Tget_range_restriction_tag(Time),
+ Date: Tget_range_restriction_tag(Date),
+ }
+)
_ns_xsd = ns.NS_XSD
_ns_wsa = ns.NS_WSA
@@ -103,11 +113,11 @@ class XmlSchema(InterfaceDocumentBase):
class.
"""
- def __init__(self, interface, element_form_default='qualified'):
+ def __init__(self, interface, element_form_default="qualified"):
super(XmlSchema, self).__init__(interface)
self.element_form_default = element_form_default
- assert element_form_default in ('qualified', 'unqualified')
+ assert element_form_default in ("qualified", "unqualified")
self.schema_dict = {}
self.validation_schema = None
@@ -139,18 +149,17 @@ def build_schema_nodes(self, with_schema_location=False):
schema = self.get_schema_node(pref)
# append import tags
- for namespace in self.interface.imports[self.interface.nsmap[pref]]:
- import_ = etree.SubElement(schema, ns.XSD('import'))
+ for namespace in self.interface.imports.get(self.interface.nsmap[pref], []):
+ import_ = etree.SubElement(schema, ns.XSD("import"))
import_.set("namespace", namespace)
import_pref = self.interface.get_namespace_prefix(namespace)
- if with_schema_location and \
- self.namespaces.get(import_pref, False):
- import_.set('schemaLocation', "%s.xsd" % import_pref)
+ if with_schema_location and self.namespaces.get(import_pref, False):
+ import_.set("schemaLocation", "%s.xsd" % import_pref)
sl = ns.schema_location.get(namespace, None)
if not (sl is None):
- import_.set('schemaLocation', sl)
+ import_.set("schemaLocation", sl)
# append simpleType and complexType tags
for node in self.namespaces[pref].types.values():
@@ -162,8 +171,8 @@ def build_schema_nodes(self, with_schema_location=False):
self.add_missing_elements_for_methods()
- self.event_manager.fire_event('document_built', self)
- self.event_manager.fire_event('xml_document_built', self)
+ self.event_manager.fire_event("document_built", self)
+ self.event_manager.fire_event("xml_document_built", self)
def add_missing_elements_for_methods(self):
def missing_methods():
@@ -182,10 +191,9 @@ def missing_methods():
name = method.in_message.get_type_name()
if not name in elements:
- element = etree.Element(ns.XSD('element'))
- element.set('name', name)
- element.set('type', method.in_message.get_type_name_ns(
- self.interface))
+ element = etree.Element(ns.XSD("element"))
+ element.set("name", name)
+ element.set("type", method.in_message.get_type_name_ns(self.interface))
elements[name] = element
schema_root.append(element)
@@ -194,10 +202,11 @@ def missing_methods():
if name is None:
name = method.out_message.get_type_name()
if not name in elements:
- element = etree.Element(ns.XSD('element'))
- element.set('name', name)
- element.set('type', method.out_message \
- .get_type_name_ns(self.interface))
+ element = etree.Element(ns.XSD("element"))
+ element.set("name", name)
+ element.set(
+ "type", method.out_message.get_type_name_ns(self.interface)
+ )
elements[name] = element
schema_root.append(element)
@@ -207,30 +216,35 @@ def build_validation_schema(self):
self.build_schema_nodes(with_schema_location=True)
pref_tns = self.interface.get_namespace_prefix(self.interface.tns)
- tmp_dir_name = tempfile.mkdtemp(prefix='spyne')
- logger.debug("generating schema for targetNamespace=%r, prefix: "
- "%r in dir %r" % (self.interface.tns, pref_tns, tmp_dir_name))
+ tmp_dir_name = tempfile.mkdtemp(prefix="spyne")
+ logger.debug(
+ "generating schema for targetNamespace=%r, prefix: "
+ "%r in dir %r" % (self.interface.tns, pref_tns, tmp_dir_name)
+ )
try:
# serialize nodes to files
for k, v in self.schema_dict.items():
file_name = os.path.join(tmp_dir_name, "%s.xsd" % k)
- with open(file_name, 'wb') as f:
+ with open(file_name, "wb") as f:
etree.ElementTree(v).write(f, pretty_print=True)
- logger.debug("writing %r for ns %s" %
- (file_name, self.interface.nsmap[k]))
+ logger.debug(
+ "writing %r for ns %s" % (file_name, self.interface.nsmap[k])
+ )
- with open(os.path.join(tmp_dir_name, "%s.xsd" % pref_tns), 'r') as f:
+ with open(os.path.join(tmp_dir_name, "%s.xsd" % pref_tns), "r") as f:
try:
self.validation_schema = etree.XMLSchema(etree.parse(f))
except Exception:
f.seek(0)
- logger.error("This could be a Spyne error. Unless you're "
- "sure the reason for this error is outside "
- "Spyne, please open a new issue with a "
- "minimal test case that reproduces it.")
+ logger.error(
+ "This could be a Spyne error. Unless you're "
+ "sure the reason for this error is outside "
+ "Spyne, please open a new issue with a "
+ "minimal test case that reproduces it."
+ )
raise
shutil.rmtree(tmp_dir_name)
@@ -245,8 +259,7 @@ def get_schema_node(self, pref):
"""Return schema node for the given namespace prefix."""
if not (pref in self.schema_dict):
- schema = etree.Element(ns.XSD('schema'),
- nsmap=self.interface.nsmap)
+ schema = etree.Element(ns.XSD("schema"), nsmap=self.interface.nsmap)
schema.set("targetNamespace", self.interface.nsmap[pref])
schema.set("elementFormDefault", self.element_form_default)
diff --git a/spyne/interface/xml_schema/defn.py b/spyne/interface/xml_schema/defn.py
index a22fb7c54..f2cec17e4 100644
--- a/spyne/interface/xml_schema/defn.py
+++ b/spyne/interface/xml_schema/defn.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -17,19 +16,12 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
-from spyne.util.six import add_metaclass
-
from spyne.const import xml
-from spyne.model.primitive import Boolean, AnyHtml
-from spyne.model.primitive import Unicode
-from spyne.model.primitive import UnsignedInteger
-from spyne.model.complex import XmlAttribute
-from spyne.model.complex import ComplexModelBase
-from spyne.model.complex import ComplexModelMeta
+from spyne.model.complex import ComplexModelBase, ComplexModelMeta, XmlAttribute
+from spyne.model.primitive import AnyHtml, Boolean, Unicode, UnsignedInteger
-@add_metaclass(ComplexModelMeta)
-class SchemaBase(ComplexModelBase):
+class SchemaBase(ComplexModelBase, metaclass=ComplexModelMeta):
__namespace__ = xml.NS_XSD
@@ -59,39 +51,42 @@ class StringAttribute(SchemaBase):
class List(SchemaBase):
_type_info = [
- ('item_type', XmlAttribute(Unicode(sub_name='itemType'))),
+ ("item_type", XmlAttribute(Unicode(sub_name="itemType"))),
]
class SimpleType(SchemaBase):
_type_info = [
- ('name', XmlAttribute(Unicode)),
- ('list', List),
- ('union', Unicode),
+ ("name", XmlAttribute(Unicode)),
+ ("list", List),
+ ("union", Unicode),
]
class Attribute(SchemaBase):
- use = XmlAttribute(Unicode)
- ref = XmlAttribute(Unicode)
- name = XmlAttribute(Unicode)
- type = XmlAttribute(Unicode)
- default = XmlAttribute(Unicode)
- simple_type = SimpleType.customize(sub_name='simpleType')
+ use = XmlAttribute(Unicode)
+ ref = XmlAttribute(Unicode)
+ name = XmlAttribute(Unicode)
+ type = XmlAttribute(Unicode)
+ default = XmlAttribute(Unicode)
+ simple_type = SimpleType.customize(sub_name="simpleType")
class Restriction(SchemaBase):
_type_info = [
- ('base', XmlAttribute(Unicode)),
- ('max_length', IntegerAttribute.customize(sub_name="maxLength")),
- ('min_length', IntegerAttribute.customize(sub_name="minLength")),
- ('pattern', StringAttribute),
- ('enumeration', StringAttribute.customize(max_occurs="unbounded")),
- ('attributes', Attribute.customize(max_occurs="unbounded",
- sub_name="attribute")),
+ ("base", XmlAttribute(Unicode)),
+ ("max_length", IntegerAttribute.customize(sub_name="maxLength")),
+ ("min_length", IntegerAttribute.customize(sub_name="minLength")),
+ ("pattern", StringAttribute),
+ ("enumeration", StringAttribute.customize(max_occurs="unbounded")),
+ (
+ "attributes",
+ Attribute.customize(max_occurs="unbounded", sub_name="attribute"),
+ ),
]
-SimpleType.append_field('restriction', Restriction)
+
+SimpleType.append_field("restriction", Restriction)
class Choice(SchemaBase):
@@ -105,8 +100,7 @@ class Sequence(SchemaBase):
class Extension(SchemaBase):
base = XmlAttribute(Unicode)
- attributes = Attribute.customize(max_occurs="unbounded",
- sub_name="attribute")
+ attributes = Attribute.customize(max_occurs="unbounded", sub_name="attribute")
class SimpleContent(SchemaBase):
@@ -118,8 +112,7 @@ class ComplexType(SchemaBase):
name = XmlAttribute(Unicode)
sequence = Sequence
simple_content = SimpleContent.customize(sub_name="simpleContent")
- attributes = Attribute.customize(max_occurs="unbounded",
- sub_name="attribute")
+ attributes = Attribute.customize(max_occurs="unbounded", sub_name="attribute")
choice = Choice
@@ -129,60 +122,69 @@ class Include(SchemaBase):
class XmlSchema10(SchemaBase):
_type_info = [
- ('target_namespace', XmlAttribute(Unicode(sub_name="targetNamespace"))),
- ('element_form_default', XmlAttribute(Unicode(
- sub_name="elementFormDefault"))),
-
- ('imports', Import.customize(max_occurs="unbounded",
- sub_name="import")),
- ('includes', Include.customize(max_occurs="unbounded",
- sub_name="include")),
- ('elements', Element.customize(max_occurs="unbounded",
- sub_name="element")),
- ('simple_types', SimpleType.customize(max_occurs="unbounded",
- sub_name="simpleType")),
- ('complex_types', ComplexType.customize(max_occurs="unbounded",
- sub_name="complexType")),
- ('attributes', Attribute.customize(max_occurs="unbounded",
- sub_name="attribute")),
+ ("target_namespace", XmlAttribute(Unicode(sub_name="targetNamespace"))),
+ ("element_form_default", XmlAttribute(Unicode(sub_name="elementFormDefault"))),
+ ("imports", Import.customize(max_occurs="unbounded", sub_name="import")),
+ ("includes", Include.customize(max_occurs="unbounded", sub_name="include")),
+ ("elements", Element.customize(max_occurs="unbounded", sub_name="element")),
+ (
+ "simple_types",
+ SimpleType.customize(max_occurs="unbounded", sub_name="simpleType"),
+ ),
+ (
+ "complex_types",
+ ComplexType.customize(max_occurs="unbounded", sub_name="complexType"),
+ ),
+ (
+ "attributes",
+ Attribute.customize(max_occurs="unbounded", sub_name="attribute"),
+ ),
]
-from itertools import chain
from inspect import isclass
+from itertools import chain
-from spyne.model import ModelBase
-from spyne.model import primitive
-from spyne.model import binary
+from spyne.model import ModelBase, binary, primitive
from spyne.model.fault import Fault
-
-TYPE_MAP = dict([
- ("{%s}%s" % (cls.get_namespace(), cls.get_type_name()), cls) for cls in
- chain(
- [v for v in vars(primitive).values()
- if getattr(v, '__type_name__', None) is not None],
+TYPE_MAP = dict(
+ [
+ ("{%s}%s" % (cls.get_namespace(), cls.get_type_name()), cls)
+ for cls in chain(
+ [
+ v
+ for v in vars(primitive).values()
+ if getattr(v, "__type_name__", None) is not None
+ ],
[
- binary.ByteArray(encoding='base64'),
- binary.ByteArray(encoding='hex'),
+ binary.ByteArray(encoding="base64"),
+ binary.ByteArray(encoding="hex"),
],
[
- primitive.Point(2), primitive.Point(3),
- primitive.Line(2), primitive.Line(3),
- primitive.Polygon(2), primitive.Polygon(3),
- primitive.MultiPoint(2), primitive.MultiPoint(3),
- primitive.MultiLine(2), primitive.MultiLine(3),
- primitive.MultiPolygon(2), primitive.MultiPolygon(3),
- ]
+ primitive.Point(2),
+ primitive.Point(3),
+ primitive.Line(2),
+ primitive.Line(3),
+ primitive.Polygon(2),
+ primitive.Polygon(3),
+ primitive.MultiPoint(2),
+ primitive.MultiPoint(3),
+ primitive.MultiLine(2),
+ primitive.MultiLine(3),
+ primitive.MultiPolygon(2),
+ primitive.MultiPolygon(3),
+ ],
)
-
if isclass(cls)
- and issubclass(cls, ModelBase)
- and not issubclass(cls, (Fault, AnyHtml))
- and not cls in (ModelBase,)
-])
+ and issubclass(cls, ModelBase)
+ and not issubclass(cls, (Fault, AnyHtml))
+ and not cls in (ModelBase,)
+ ]
+)
-if __name__ == '__main__':
+if __name__ == "__main__":
from pprint import pprint
+
pprint(TYPE_MAP)
diff --git a/spyne/interface/xml_schema/genpy.py b/spyne/interface/xml_schema/genpy.py
index 21784f8dd..d1a4f1561 100644
--- a/spyne/interface/xml_schema/genpy.py
+++ b/spyne/interface/xml_schema/genpy.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -26,28 +25,28 @@
"""
import logging
-logger = logging.getLogger(__name__)
-import spyne
+logger = logging.getLogger(__name__)
+from collections import defaultdict
from datetime import datetime
from itertools import chain
-from collections import defaultdict
+import spyne
from spyne.model import SimpleModel
-from spyne.model.complex import XmlModifier
-from spyne.model.complex import ComplexModelBase
+from spyne.model.complex import ComplexModelBase, XmlModifier
def gen_fn_from_tns(tns):
- return tns \
- .replace('http://', '') \
- .replace('https://', '') \
- .replace('/', '') \
- .replace('.', '_') \
- .replace(':', '_') \
- .replace('#', '') \
- .replace('-', '_')
+ return (
+ tns.replace("http://", "")
+ .replace("https://", "")
+ .replace("/", "")
+ .replace(".", "_")
+ .replace(":", "_")
+ .replace("#", "")
+ .replace("-", "_")
+ )
class CodeGenerator(object):
@@ -59,7 +58,7 @@ def __init__(self, fn_tns_mapper=gen_fn_from_tns):
self.fn_tns_mapper = fn_tns_mapper
def gen_modifier(self, t):
- return '%s(%s)' % (t.__name__, self.gen_dispatch(t.type))
+ return "%s(%s)" % (t.__name__, self.gen_dispatch(t.type))
def gen_simple(self, t):
return t.__name__
@@ -71,11 +70,13 @@ def gen_complex(self, t):
class %s(_ComplexBase):
_type_info = [""" % (t.get_type_name()))
- for k,v in t._type_info.items():
- if not issubclass(v, ComplexModelBase) or \
- v.get_namespace() != self.tns or \
- v in self.classes or \
- getattr(v, '__orig__', None) in self.classes:
+ for k, v in t._type_info.items():
+ if (
+ not issubclass(v, ComplexModelBase)
+ or v.get_namespace() != self.tns
+ or v in self.classes
+ or getattr(v, "__orig__", None) in self.classes
+ ):
retval.append(" ('%s', %s)," % (k, self.gen_dispatch(v)))
else:
self.pending[v.get_type_name()].append((k, t.get_type_name()))
@@ -84,7 +85,7 @@ class %s(_ComplexBase):
self.classes.add(t)
- for k,orig_t in self.pending[t.get_type_name()]:
+ for k, orig_t in self.pending[t.get_type_name()]:
retval.append('%s._type_info["%s"] = %s' % (orig_t, k, t.get_type_name()))
return retval
@@ -106,26 +107,27 @@ def gen_dispatch(self, t):
def genpy(self, tns, s):
self.tns = tns
- retval = [u"""# encoding: utf8
+ retval = [
+ """# encoding: utf8
# Automatically generated by Spyne %s at %s.
# Modify at your own risk.
from spyne.model import *
-""" % (spyne.__version__, datetime.now().replace(microsecond=0).isoformat(' ')),
-"", # imports
-"""
+""" % (spyne.__version__, datetime.now().replace(microsecond=0).isoformat(" ")),
+ "", # imports
+ """
class _ComplexBase(ComplexModelBase):
__namespace__ = '%s'
- __metaclass__ = ComplexModelMeta""" % tns
-]
+ __metaclass__ = ComplexModelMeta""" % tns,
+ ]
for n, t in s.types.items():
if issubclass(t, ComplexModelBase):
retval.extend(self.gen_complex(t))
else:
- retval.append('%s = %s' % (n, self.gen_dispatch(t)))
+ retval.append("%s = %s" % (n, self.gen_dispatch(t)))
self.simples.add(n)
for i in self.imports:
@@ -134,11 +136,10 @@ class _ComplexBase(ComplexModelBase):
retval.append("")
retval.append("")
- retval.append('__all__ = [')
- for c in sorted(chain([c.get_type_name() for c in self.classes],
- self.simples)):
- retval.append(" '%s'," % c)
- retval.append(']')
+ retval.append("__all__ = [")
+ for c in sorted(chain([c.get_type_name() for c in self.classes], self.simples)):
+ retval.append(" '%s'," % c)
+ retval.append("]")
retval.append("")
- return '\n'.join(retval)
+ return "\n".join(retval)
diff --git a/spyne/interface/xml_schema/model.py b/spyne/interface/xml_schema/model.py
index 6b491baab..d50023c39 100644
--- a/spyne/interface/xml_schema/model.py
+++ b/spyne/interface/xml_schema/model.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -20,23 +19,30 @@
"""The ``spyne.interface.xml_schema.model`` module contains type-specific logic
for schema generation."""
-
import logging
+
logger = logging.getLogger(__name__)
+from collections import defaultdict, deque
from decimal import Decimal as D
-from collections import deque, defaultdict
from lxml import etree
-from spyne.model import ModelBase, XmlAttribute, AnyXml, Unicode, XmlData, \
- Decimal, Integer
from spyne.const.xml import NS_XSD, XSD
+from spyne.model import (
+ AnyXml,
+ Decimal,
+ Integer,
+ ModelBase,
+ Unicode,
+ XmlAttribute,
+ XmlData,
+)
+from spyne.protocol.xml import XmlDocument
from spyne.util import memoize
from spyne.util.cdict import cdict
from spyne.util.etreeconv import dict_to_etree
-from spyne.util.six import string_types
-from spyne.protocol.xml import XmlDocument
+
_prot = XmlDocument()
# In Xml Schema, some customizations do not need a class to be extended -- they
@@ -44,25 +50,38 @@
# min_occurs. The dict below contains list of parameters that do warrant a
# proper subclass definition for each type. This must be updated as the Xml
# Schema implementation makes progress.
-ATTR_NAMES = cdict({
- ModelBase: set(['values']),
- Decimal: set(['pattern', 'gt', 'ge', 'lt', 'le', 'values', 'total_digits',
- 'fraction_digits']),
- Integer: set(['pattern', 'gt', 'ge', 'lt', 'le', 'values', 'total_digits']),
- Unicode: set(['values', 'min_len', 'max_len', 'pattern']),
-})
+ATTR_NAMES = cdict(
+ {
+ ModelBase: set(["values"]),
+ Decimal: set(
+ [
+ "pattern",
+ "gt",
+ "ge",
+ "lt",
+ "le",
+ "values",
+ "total_digits",
+ "fraction_digits",
+ ]
+ ),
+ Integer: set(["pattern", "gt", "ge", "lt", "le", "values", "total_digits"]),
+ Unicode: set(["values", "min_len", "max_len", "pattern"]),
+ }
+)
+
def xml_attribute_add(cls, name, element, document):
- element.set('name', name)
- element.set('type', cls.type.get_type_name_ns(document.interface))
+ element.set("name", name)
+ element.set("type", cls.type.get_type_name_ns(document.interface))
if cls._use is not None:
- element.set('use', cls._use)
+ element.set("use", cls._use)
d = cls.type.Attributes.default
if d is not None:
- element.set('default', _prot.to_unicode(cls.type, d))
+ element.set("default", _prot.to_unicode(cls.type, d))
def _check_extension_attrs(cls):
@@ -73,12 +92,12 @@ def _check_extension_attrs(cls):
eattrs = extends.Attributes
cattrs = cls.Attributes
- ckeys = set([k for k in vars(cls.Attributes) if not k.startswith('_')])
- ekeys = set([k for k in vars(extends.Attributes) if not k.startswith('_')])
+ ckeys = set([k for k in vars(cls.Attributes) if not k.startswith("_")])
+ ekeys = set([k for k in vars(extends.Attributes) if not k.startswith("_")])
# get the attributes different from the parent class
diff = set()
- for k in (ckeys | ekeys):
+ for k in ckeys | ekeys:
if getattr(eattrs, k, None) != getattr(cattrs, k, None):
diff.add(k)
@@ -93,23 +112,24 @@ def _check_extension_attrs(cls):
return retval
+
# noinspection PyDefaultArgument
def simple_get_restriction_tag(document, cls):
extends = _check_extension_attrs(cls)
if extends is None:
return
- simple_type = etree.Element(XSD('simpleType'))
+ simple_type = etree.Element(XSD("simpleType"))
- simple_type.set('name', cls.get_type_name())
+ simple_type.set("name", cls.get_type_name())
document.add_simple_type(cls, simple_type)
- restriction = etree.SubElement(simple_type, XSD('restriction'))
- restriction.set('base', extends.get_type_name_ns(document.interface))
+ restriction = etree.SubElement(simple_type, XSD("restriction"))
+ restriction.set("base", extends.get_type_name_ns(document.interface))
for v in cls.Attributes.values:
- enumeration = etree.SubElement(restriction, XSD('enumeration'))
- enumeration.set('value', XmlDocument().to_unicode(cls, v))
+ enumeration = etree.SubElement(restriction, XSD("enumeration"))
+ enumeration.set("value", XmlDocument().to_unicode(cls, v))
return restriction
@@ -118,28 +138,29 @@ def simple_add(document, cls, tags):
if not cls.is_default(cls):
document.get_restriction_tag(cls)
+
def byte_array_add(document, cls, tags):
simple_add(document, cls, tags)
def complex_add(document, cls, tags):
- complex_type = etree.Element(XSD('complexType'))
- complex_type.set('name', cls.get_type_name())
+ complex_type = etree.Element(XSD("complexType"))
+ complex_type.set("name", cls.get_type_name())
doc_text = cls.get_documentation()
if doc_text or cls.Annotations.appinfo is not None:
- annotation = etree.SubElement(complex_type, XSD('annotation'))
+ annotation = etree.SubElement(complex_type, XSD("annotation"))
if doc_text:
- doc = etree.SubElement(annotation, XSD('documentation'))
+ doc = etree.SubElement(annotation, XSD("documentation"))
doc.text = doc_text
_ai = cls.Annotations.appinfo
if _ai is not None:
- appinfo = etree.SubElement(annotation, XSD('appinfo'))
+ appinfo = etree.SubElement(annotation, XSD("appinfo"))
if isinstance(_ai, dict):
dict_to_etree(_ai, appinfo)
- elif isinstance(_ai, string_types):
+ elif isinstance(_ai, str):
appinfo.text = _ai
elif isinstance(_ai, etree._Element):
@@ -151,14 +172,18 @@ def complex_add(document, cls, tags):
appinfo.append(get_object_as_xml(_ai))
sequence_parent = complex_type
- extends = getattr(cls, '__extends__', None)
+ extends = getattr(cls, "__extends__", None)
type_info = cls._type_info
if extends is not None:
- if (extends.get_type_name() == cls.get_type_name() and
- extends.get_namespace() == cls.get_namespace()):
- raise Exception("%r can't extend %r because they are both '{%s}%s'"
- % (cls, extends, cls.get_namespace(), cls.get_type_name()))
+ if (
+ extends.get_type_name() == cls.get_type_name()
+ and extends.get_namespace() == cls.get_namespace()
+ ):
+ raise Exception(
+ "%r can't extend %r because they are both '{%s}%s'"
+ % (cls, extends, cls.get_namespace(), cls.get_type_name())
+ )
if extends.Attributes.exc_interface:
# If the parent class is private, it won't be in the schema, so we
@@ -166,26 +191,26 @@ def complex_add(document, cls, tags):
type_info = cls.get_simple_type_info(cls)
else:
- complex_content = etree.SubElement(complex_type,
- XSD('complexContent'))
- extension = etree.SubElement(complex_content, XSD('extension'))
- extension.set('base', extends.get_type_name_ns(document.interface))
+ complex_content = etree.SubElement(complex_type, XSD("complexContent"))
+ extension = etree.SubElement(complex_content, XSD("extension"))
+ extension.set("base", extends.get_type_name_ns(document.interface))
sequence_parent = extension
if cls.Attributes._xml_tag_body_as is not None:
for xtba_key, xtba_type in cls.Attributes._xml_tag_body_as:
- _sc = etree.SubElement(sequence_parent, XSD('simpleContent'))
- xtba_ext = etree.SubElement(_sc, XSD('extension'))
- xtba_ext.attrib['base'] = xtba_type.type.get_type_name_ns(
- document.interface)
+ _sc = etree.SubElement(sequence_parent, XSD("simpleContent"))
+ xtba_ext = etree.SubElement(_sc, XSD("extension"))
+ xtba_ext.attrib["base"] = xtba_type.type.get_type_name_ns(
+ document.interface
+ )
- sequence = etree.Element(XSD('sequence'))
+ sequence = etree.Element(XSD("sequence"))
deferred = deque()
- choice_tags = defaultdict(lambda: etree.Element(XSD('choice')))
+ choice_tags = defaultdict(lambda: etree.Element(XSD("choice")))
for k, v in type_info.items():
- assert isinstance(k, string_types)
+ assert isinstance(k, str)
assert issubclass(v, ModelBase)
a = v.Attributes
@@ -196,7 +221,7 @@ def complex_add(document, cls, tags):
continue
if issubclass(v, XmlAttribute):
- deferred.append((k,v))
+ deferred.append((k, v))
continue
document.add(v, tags)
@@ -204,53 +229,57 @@ def complex_add(document, cls, tags):
name = a.sub_name
if name is None:
name = k
- #ns = a.sub_ns
- #if ns is not None:
+ # ns = a.sub_ns
+ # if ns is not None:
# name = "{%s}%s" % (ns, name)
type_name_ns = v.get_type_name_ns(document.interface)
- if v.__extends__ is not None and v.__orig__ is not None and \
- _check_extension_attrs(v) is None:
+ if (
+ v.__extends__ is not None
+ and v.__orig__ is not None
+ and _check_extension_attrs(v) is None
+ ):
type_name_ns = v.__orig__.get_type_name_ns(document.interface)
member = etree.Element(a.schema_tag)
- if a.schema_tag == XSD('element'):
- member.set('name', name)
- member.set('type', type_name_ns)
+ if a.schema_tag == XSD("element"):
+ member.set("name", name)
+ member.set("type", type_name_ns)
- elif a.schema_tag == XSD('any') and issubclass(v, AnyXml):
+ elif a.schema_tag == XSD("any") and issubclass(v, AnyXml):
if a.namespace is not None:
- member.set('namespace', a.namespace)
+ member.set("namespace", a.namespace)
if a.process_contents is not None:
- member.set('processContents', a.process_contents)
+ member.set("processContents", a.process_contents)
else:
- raise ValueError("Unhandled schema_tag / type combination. %r %r"
- % (v, a.schema_tag))
+ raise ValueError(
+ "Unhandled schema_tag / type combination. %r %r" % (v, a.schema_tag)
+ )
if a.min_occurs != 1: # 1 is the xml schema default
- member.set('minOccurs', str(a.min_occurs))
+ member.set("minOccurs", str(a.min_occurs))
if a.max_occurs != 1: # 1 is the xml schema default
val = a.max_occurs
- if val in (D('inf'), float('inf')):
- val = 'unbounded'
+ if val in (D("inf"), float("inf")):
+ val = "unbounded"
else:
val = str(val)
- member.set('maxOccurs', val)
+ member.set("maxOccurs", val)
if a.default is not None:
- member.set('default', _prot.to_unicode(v, a.default))
+ member.set("default", _prot.to_unicode(v, a.default))
- if bool(a.nillable) != False: # False is the xml schema default
- member.set('nillable', 'true')
+ if bool(a.nillable) != False: # False is the xml schema default
+ member.set("nillable", "true")
v_doc_text = v.get_documentation()
if v_doc_text:
# Doesn't support multi-language documentation
- annotation = etree.SubElement(member, XSD('annotation'))
- doc = etree.SubElement(annotation, XSD('documentation'))
+ annotation = etree.SubElement(member, XSD("annotation"))
+ doc = etree.SubElement(annotation, XSD("documentation"))
doc.text = v_doc_text
if a.xml_choice_group is None:
@@ -264,8 +293,8 @@ def complex_add(document, cls, tags):
sequence_parent.append(sequence)
_ext_elements = dict()
- for k,v in deferred:
- attribute = etree.Element(XSD('attribute'))
+ for k, v in deferred:
+ attribute = etree.Element(XSD("attribute"))
xml_attribute_add(v, k, attribute, document)
if cls.Attributes._xml_tag_body_as is None:
@@ -277,27 +306,29 @@ def complex_add(document, cls, tags):
# simple node
complex_type_name = cls.Attributes.sub_name or cls.get_type_name()
- element = etree.Element(XSD('element'))
- element.set('name', complex_type_name)
- element.set('type', cls.get_type_name_ns(document.interface))
+ element = etree.Element(XSD("element"))
+ element.set("name", complex_type_name)
+ element.set("type", cls.get_type_name_ns(document.interface))
document.add_element(cls, element)
def enum_add(document, cls, tags):
- simple_type = etree.Element(XSD('simpleType'))
- simple_type.set('name', cls.get_type_name())
+ simple_type = etree.Element(XSD("simpleType"))
+ simple_type.set("name", cls.get_type_name())
- restriction = etree.SubElement(simple_type, XSD('restriction'))
- restriction.set('base', '%s:string' %
- document.interface.get_namespace_prefix(NS_XSD))
+ restriction = etree.SubElement(simple_type, XSD("restriction"))
+ restriction.set(
+ "base", "%s:string" % document.interface.get_namespace_prefix(NS_XSD)
+ )
for v in cls.__values__:
- enumeration = etree.SubElement(restriction, XSD('enumeration'))
- enumeration.set('value', v)
+ enumeration = etree.SubElement(restriction, XSD("enumeration"))
+ enumeration.set("value", v)
document.add_simple_type(cls, simple_type)
+
fault_add = complex_add
@@ -308,22 +339,22 @@ def unicode_get_restriction_tag(document, cls):
# length
if cls.Attributes.min_len == cls.Attributes.max_len:
- length = etree.SubElement(restriction, XSD('length'))
- length.set('value', str(cls.Attributes.min_len))
+ length = etree.SubElement(restriction, XSD("length"))
+ length.set("value", str(cls.Attributes.min_len))
else:
if cls.Attributes.min_len != Unicode.Attributes.min_len:
- min_l = etree.SubElement(restriction, XSD('minLength'))
- min_l.set('value', str(cls.Attributes.min_len))
+ min_l = etree.SubElement(restriction, XSD("minLength"))
+ min_l.set("value", str(cls.Attributes.min_len))
if cls.Attributes.max_len != Unicode.Attributes.max_len:
- max_l = etree.SubElement(restriction, XSD('maxLength'))
- max_l.set('value', str(cls.Attributes.max_len))
+ max_l = etree.SubElement(restriction, XSD("maxLength"))
+ max_l.set("value", str(cls.Attributes.max_len))
# pattern
if cls.Attributes.pattern != Unicode.Attributes.pattern:
- pattern = etree.SubElement(restriction, XSD('pattern'))
- pattern.set('value', cls.Attributes.pattern)
+ pattern = etree.SubElement(restriction, XSD("pattern"))
+ pattern.set("value", cls.Attributes.pattern)
return restriction
@@ -336,32 +367,33 @@ def Tget_range_restriction_tag(T):
a function that generates range restriction tags.
"""
- from spyne.model.primitive import Decimal
- from spyne.model.primitive import Integer
+ from spyne.model.primitive import Decimal, Integer
if issubclass(T, Decimal):
+
def _get_float_restrictions(prot, restriction, cls):
if cls.Attributes.fraction_digits != T.Attributes.fraction_digits:
- elt = etree.SubElement(restriction, XSD('fractionDigits'))
- elt.set('value', prot.to_unicode(cls,
- cls.Attributes.fraction_digits))
+ elt = etree.SubElement(restriction, XSD("fractionDigits"))
+ elt.set("value", prot.to_unicode(cls, cls.Attributes.fraction_digits))
def _get_integer_restrictions(prot, restriction, cls):
if cls.Attributes.total_digits != T.Attributes.total_digits:
- elt = etree.SubElement(restriction, XSD('totalDigits'))
- elt.set('value', prot.to_unicode(cls,
- cls.Attributes.total_digits))
+ elt = etree.SubElement(restriction, XSD("totalDigits"))
+ elt.set("value", prot.to_unicode(cls, cls.Attributes.total_digits))
if issubclass(T, Integer):
+
def _get_additional_restrictions(prot, restriction, cls):
_get_integer_restrictions(prot, restriction, cls)
else:
+
def _get_additional_restrictions(prot, restriction, cls):
_get_integer_restrictions(prot, restriction, cls)
_get_float_restrictions(prot, restriction, cls)
else:
+
def _get_additional_restrictions(prot, restriction, cls):
pass
@@ -371,24 +403,24 @@ def _get_range_restriction_tag(document, cls):
return
if cls.Attributes.gt != T.Attributes.gt:
- elt = etree.SubElement(restriction, XSD('minExclusive'))
- elt.set('value', prot.to_unicode(cls, cls.Attributes.gt))
+ elt = etree.SubElement(restriction, XSD("minExclusive"))
+ elt.set("value", prot.to_unicode(cls, cls.Attributes.gt))
if cls.Attributes.ge != T.Attributes.ge:
- elt = etree.SubElement(restriction, XSD('minInclusive'))
- elt.set('value', prot.to_unicode(cls, cls.Attributes.ge))
+ elt = etree.SubElement(restriction, XSD("minInclusive"))
+ elt.set("value", prot.to_unicode(cls, cls.Attributes.ge))
if cls.Attributes.lt != T.Attributes.lt:
- elt = etree.SubElement(restriction, XSD('maxExclusive'))
- elt.set('value', prot.to_unicode(cls, cls.Attributes.lt))
+ elt = etree.SubElement(restriction, XSD("maxExclusive"))
+ elt.set("value", prot.to_unicode(cls, cls.Attributes.lt))
if cls.Attributes.le != T.Attributes.le:
- elt = etree.SubElement(restriction, XSD('maxInclusive'))
- elt.set('value', prot.to_unicode(cls, cls.Attributes.le))
+ elt = etree.SubElement(restriction, XSD("maxInclusive"))
+ elt.set("value", prot.to_unicode(cls, cls.Attributes.le))
if cls.Attributes.pattern != T.Attributes.pattern:
- elt = etree.SubElement(restriction, XSD('pattern'))
- elt.set('value', cls.Attributes.pattern)
+ elt = etree.SubElement(restriction, XSD("pattern"))
+ elt.set("value", cls.Attributes.pattern)
_get_additional_restrictions(prot, restriction, cls)
diff --git a/spyne/interface/xml_schema/parser.py b/spyne/interface/xml_schema/parser.py
index 010c912da..ce8cd0abf 100644
--- a/spyne/interface/xml_schema/parser.py
+++ b/spyne/interface/xml_schema/parser.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -25,32 +24,32 @@
#
import logging
+
logger = logging.getLogger(__name__)
import os
-
+from collections import defaultdict
from copy import copy
-from pprint import pformat
from itertools import chain
-from collections import defaultdict
-from os.path import dirname, abspath, join
+from os.path import abspath, dirname, join
+from pprint import pformat
from lxml import etree
-from spyne.util import memoize
-from spyne.util.odict import odict
-
-from spyne.model import Null, XmlData, XmlAttribute, Array, ComplexModelBase, \
- ComplexModelMeta
+from spyne.interface.xml_schema.defn import TYPE_MAP, SchemaBase, XmlSchema10
+from spyne.model import (
+ Array,
+ ComplexModelBase,
+ ComplexModelMeta,
+ Null,
+ XmlAttribute,
+ XmlData,
+)
from spyne.model.complex import XmlModifier
-
from spyne.protocol.xml import XmlDocument
-
-from spyne.interface.xml_schema.defn import TYPE_MAP
-from spyne.interface.xml_schema.defn import SchemaBase
-from spyne.interface.xml_schema.defn import XmlSchema10
-
-from spyne.util.color import R, G, B, MAG, YEL
+from spyne.util import memoize
+from spyne.util.color import MAG, YEL, B, G, R
+from spyne.util.odict import odict
PARSER = etree.XMLParser(remove_comments=True)
@@ -75,23 +74,26 @@ def Thier_repr(with_ns=False):
"""
if with_ns is False:
+
def get_class_name(c):
return c.get_type_name()
elif with_ns is True or with_ns == 1:
+
def get_class_name(c):
return "{%s}%s" % (c.get_namespace(), c.get_type_name())
else:
+
def get_class_name(c):
return with_ns(c.get_namespace(), c.get_type_name())
- def hier_repr(inst, i0=0, I=' ', tags=None):
+ def hier_repr(inst, i0=0, I=" ", tags=None):
if tags is None:
tags = set()
cls = inst.__class__
- if not hasattr(cls, '_type_info'):
+ if not hasattr(cls, "_type_info"):
return repr(inst)
clsid = "%s" % (get_class_name(cls))
@@ -103,7 +105,7 @@ def hier_repr(inst, i0=0, I=' ', tags=None):
i1 = i0 + 1
i2 = i1 + 1
- retval = [clsid, '(']
+ retval = [clsid, "("]
xtba = cls.Attributes._xml_tag_body_as
if xtba is not None:
@@ -113,32 +115,32 @@ def hier_repr(inst, i0=0, I=' ', tags=None):
value = getattr(inst, xtba_key, None)
retval.append("%s,\n" % hier_repr(value, i1, I, tags))
else:
- retval.append('\n')
+ retval.append("\n")
else:
- retval.append('\n')
+ retval.append("\n")
for k, v in inst.get_flat_type_info(cls).items():
value = getattr(inst, k, None)
- if (issubclass(v, Array) or v.Attributes.max_occurs > 1) and \
- value is not None:
+ if (
+ issubclass(v, Array) or v.Attributes.max_occurs > 1
+ ) and value is not None:
retval.append("%s%s=[\n" % (I * i1, k))
for subval in value:
- retval.append("%s%s,\n" % (I * i2,
- hier_repr(subval, i2, I, tags)))
- retval.append('%s],\n' % (I * i1))
+ retval.append("%s%s,\n" % (I * i2, hier_repr(subval, i2, I, tags)))
+ retval.append("%s],\n" % (I * i1))
elif issubclass(v, XmlData):
pass
else:
- retval.append("%s%s=%s,\n" % (I * i1, k,
- hier_repr(value, i1, I, tags)))
+ retval.append("%s%s=%s,\n" % (I * i1, k, hier_repr(value, i1, I, tags)))
- retval.append('%s)' % (I * i0))
- return ''.join(retval)
+ retval.append("%s)" % (I * i0))
+ return "".join(retval)
return hier_repr
+
SchemaBase.__repr__ = Thier_repr()
hier_repr = Thier_repr()
@@ -146,8 +148,9 @@ def hier_repr(inst, i0=0, I=' ', tags=None):
class XmlSchemaParser(object):
- def __init__(self, files, base_dir=None, repr_=Thier_repr(with_ns=False),
- skip_errors=False):
+ def __init__(
+ self, files, base_dir=None, repr_=Thier_repr(with_ns=False), skip_errors=False
+ ):
self.retval = {}
self.indent = 0
self.files = files
@@ -188,7 +191,7 @@ def clone(self, indent=0, base_dir=None):
return retval
def debug0(self, s, *args, **kwargs):
- logger.debug("%s%s" % (" " * self.indent, s), *args, **kwargs)
+ logger.debug("%s%s" % (" " * self.indent, s), *args, **kwargs)
def debug1(self, s, *args, **kwargs):
logger.debug("%s%s" % (" " * (self.indent + 1), s), *args, **kwargs)
@@ -197,7 +200,7 @@ def debug2(self, s, *args, **kwargs):
logger.debug("%s%s" % (" " * (self.indent + 2), s), *args, **kwargs)
def parse_schema_file(self, file_name):
- elt = etree.fromstring(open(file_name, 'rb').read(), parser=PARSER)
+ elt = etree.fromstring(open(file_name, "rb").read(), parser=PARSER)
return self.parse_schema(elt)
def process_includes(self, include):
@@ -208,7 +211,7 @@ def process_includes(self, include):
self.debug1("including %s %s", self.base_dir, file_name)
file_name = abspath(join(self.base_dir, file_name))
- data = open(file_name, 'rb').read()
+ data = open(file_name, "rb").read()
elt = etree.fromstring(data, parser=PARSER)
self.nsmap.update(elt.nsmap)
self.prefmap = dict([(v, k) for k, v in self.nsmap.items()])
@@ -222,7 +225,7 @@ def process_includes(self, include):
self.nsmap.update(child_ctx.nsmap)
self.prefmap = dict([(v, k) for k, v in self.nsmap.items()])
- for attr in ('imports', 'simple_types', 'complex_types', 'elements'):
+ for attr in ("imports", "simple_types", "complex_types", "elements"):
sub = getattr(sub_schema, attr)
if sub is None:
sub = []
@@ -238,20 +241,26 @@ def process_includes(self, include):
def process_simple_type_list(self, s, name=None):
item_type = s.list.item_type
if item_type is None:
- self.debug1("skipping simple type: %s because its list itemType "
- "could not be found", name)
+ self.debug1(
+ "skipping simple type: %s because its list itemType "
+ "could not be found",
+ name,
+ )
return
base = self.get_type(item_type)
if base is None:
self.pending_simple_types[self.get_name(item_type)].add((s, name))
- self.debug1("pending simple type list: %s "
- "because of unseen base %s", name, item_type)
+ self.debug1(
+ "pending simple type list: %s " "because of unseen base %s",
+ name,
+ item_type,
+ )
return
self.debug1("adding simple type list: %s", name)
- retval = Array(base, serialize_as='sd-list') # FIXME: to be implemented
+ retval = Array(base, serialize_as="sd-list") # FIXME: to be implemented
retval.__type_name__ = name
retval.__namespace__ = self.tns
@@ -261,15 +270,19 @@ def process_simple_type_list(self, s, name=None):
def process_simple_type_restriction(self, s, name=None):
base_name = s.restriction.base
if base_name is None:
- self.debug1("skipping simple type: %s because its restriction base "
- "could not be found", name)
+ self.debug1(
+ "skipping simple type: %s because its restriction base "
+ "could not be found",
+ name,
+ )
return
base = self.get_type(base_name)
if base is None:
self.pending_simple_types[self.get_name(base_name)].add((s, name))
- self.debug1("pending simple type: %s because of unseen base %s",
- name, base_name)
+ self.debug1(
+ "pending simple type: %s because of unseen base %s", name, base_name
+ )
return
@@ -278,19 +291,19 @@ def process_simple_type_restriction(self, s, name=None):
kwargs = {}
restriction = s.restriction
if restriction.enumeration:
- kwargs['values'] = [e.value for e in restriction.enumeration]
+ kwargs["values"] = [e.value for e in restriction.enumeration]
if restriction.max_length:
if restriction.max_length.value:
- kwargs['max_len'] = int(restriction.max_length.value)
+ kwargs["max_len"] = int(restriction.max_length.value)
if restriction.min_length:
if restriction.min_length.value:
- kwargs['min_len'] = int(restriction.min_length.value)
+ kwargs["min_len"] = int(restriction.min_length.value)
if restriction.pattern:
if restriction.pattern.value:
- kwargs['pattern'] = restriction.pattern.value
+ kwargs["pattern"] = restriction.pattern.value
retval = base.customize(**kwargs)
retval.__type_name__ = name
@@ -305,8 +318,9 @@ def process_simple_type_restriction(self, s, name=None):
return retval
def process_simple_type_union(self, s, name=None):
- self.debug1("skipping simple type: %s because is not "
- "implemented", name)
+ self.debug1(
+ "skipping simple type: %s because is not " "implemented", name
+ )
def process_simple_type(self, s, name=None):
"""Returns the simple Spyne type from `` tag."""
@@ -373,20 +387,20 @@ def process_attribute(self, a):
t = self.get_type(a.type)
if t is None:
- raise ValueError(a, 'type %r not found' % a.type)
+ raise ValueError(a, "type %r not found" % a.type)
elif a.simple_type is not None:
t = self.process_simple_type(a.simple_type, a.name)
if t is None:
- raise ValueError(a, 'simple type %r not found' % a.simple_type)
+ raise ValueError(a, "simple type %r not found" % a.simple_type)
else:
raise Exception("dunno attr")
kwargs = {}
if a.default is not None:
- kwargs['default'] = _prot.from_unicode(t, a.default)
+ kwargs["default"] = _prot.from_unicode(t, a.default)
if len(kwargs) > 0:
t = t.customize(**kwargs)
@@ -415,30 +429,30 @@ def process_type(tn, name, wrapper=None, element=None, attribute=None):
kwargs = {}
if element is not None:
if e.min_occurs != "0": # spyne default
- kwargs['min_occurs'] = int(e.min_occurs)
+ kwargs["min_occurs"] = int(e.min_occurs)
if e.max_occurs == "unbounded":
- kwargs['max_occurs'] = e.max_occurs
+ kwargs["max_occurs"] = e.max_occurs
elif e.max_occurs != "1":
- kwargs['max_occurs'] = int(e.max_occurs)
+ kwargs["max_occurs"] = int(e.max_occurs)
if e.nillable != True: # spyne default
- kwargs['nillable'] = e.nillable
+ kwargs["nillable"] = e.nillable
if e.default is not None:
- kwargs['default'] = _prot.from_unicode(t, e.default)
+ kwargs["default"] = _prot.from_unicode(t, e.default)
if len(kwargs) > 0:
t = t.customize(**kwargs)
if attribute is not None:
if attribute.default is not None:
- kwargs['default'] = _prot.from_unicode(t, a.default)
+ kwargs["default"] = _prot.from_unicode(t, a.default)
if len(kwargs) > 0:
t = t.customize(**kwargs)
- ti.append( (name, wrapper(t)) )
+ ti.append((name, wrapper(t)))
self.debug2(" found: %r(%s), c: %r", key, tn, kwargs)
def process_element(e):
@@ -528,13 +542,15 @@ def process_element(e):
r._type_info.update(ti)
else:
- cls_dict = odict({
- '__type_name__': c.name,
- '__namespace__': self.tns,
- '_type_info': ti,
- })
+ cls_dict = odict(
+ {
+ "__type_name__": c.name,
+ "__namespace__": self.tns,
+ "_type_info": ti,
+ }
+ )
if self.repr is not None:
- cls_dict['__repr__'] = self.repr
+ cls_dict["__repr__"] = self.repr
r = ComplexModelMeta(str(c.name), (base,), cls_dict)
self.retval[self.tns].types[c.name] = r
@@ -543,7 +559,7 @@ def process_element(e):
def get_name(self, tn):
if tn.startswith("{"):
- ns, qn = tn[1:].split('}', 1)
+ ns, qn = tn[1:].split("}", 1)
elif ":" in tn:
ns, qn = tn.split(":", 1)
@@ -576,8 +592,7 @@ def get_type(self, tn):
else:
retval = self.get_type("{%s}%s" % (ns, e.type))
if retval is None and None in self.nsmap:
- retval = self.get_type("{%s}%s" %
- (self.nsmap[None], e.type))
+ retval = self.get_type("{%s}%s" % (self.nsmap[None], e.type))
return retval
return TYPE_MAP.get("{%s}%s" % (ns, qn))
@@ -594,8 +609,7 @@ def process_pending(self):
def print_pending(self, fail=False):
ptt_pending = sum((len(v) for v in self.pending_simple_types.values())) > 0
- if len(self.pending_elements) > 0 or len(self.pending_types) > 0 or \
- ptt_pending:
+ if len(self.pending_elements) > 0 or len(self.pending_types) > 0 or ptt_pending:
if fail:
logging.basicConfig(level=logging.DEBUG)
self.debug0("%" * 50)
@@ -627,7 +641,7 @@ def parse_schema(self, elt):
self.tns = tns = schema.target_namespace
if self.tns is None:
- self.tns = tns = '__no_ns__'
+ self.tns = tns = "__no_ns__"
if tns in self.retval:
return
self.retval[tns] = _Schema()
@@ -640,11 +654,9 @@ def parse_schema(self, elt):
if schema.elements:
schema.elements = odict([(e.name, e) for e in schema.elements])
if schema.complex_types:
- schema.complex_types = odict([(c.name, c)
- for c in schema.complex_types])
+ schema.complex_types = odict([(c.name, c) for c in schema.complex_types])
if schema.simple_types:
- schema.simple_types = odict([(s.name, s)
- for s in schema.simple_types])
+ schema.simple_types = odict([(s.name, s) for s in schema.simple_types])
if schema.attributes:
schema.attributes = odict([(a.name, a) for a in schema.attributes])
@@ -663,8 +675,9 @@ def parse_schema(self, elt):
self.process_simple_type(s)
# no simple types should have been left behind.
- assert sum((len(v) for v in self.pending_simple_types.values())) == 0, \
- self.pending_simple_types.values()
+ assert (
+ sum((len(v) for v in self.pending_simple_types.values())) == 0
+ ), self.pending_simple_types.values()
self.debug0("4 %s processing attributes", G(tns))
if schema.attributes:
@@ -689,7 +702,7 @@ def parse_schema(self, elt):
# This is needed for schemas with circular imports
for c in chain([self], self.children):
c.print_pending()
- self.debug0('')
+ self.debug0("")
# FIXME: should put this in a while loop that loops until no
# changes occur
@@ -697,7 +710,7 @@ def parse_schema(self, elt):
c.process_pending()
for c in chain([self], self.children):
c.process_pending()
- self.debug0('')
+ self.debug0("")
for c in chain([self], self.children):
c.print_pending(fail=(not self.skip_errors))
diff --git a/spyne/model/__init__.py b/spyne/model/__init__.py
index 929a807b1..a70098540 100644
--- a/spyne/model/__init__.py
+++ b/spyne/model/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -16,17 +15,21 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
+# fmt: off
+# isort: skip_file
"""The ``spyne.model`` package contains data types that Spyne is able to
distinguish. These are just type markers, they are not of much use without
protocols.
"""
-from spyne.model._base import Ignored
-from spyne.model._base import ModelBase
-from spyne.model._base import PushBase
-from spyne.model._base import Null
-from spyne.model._base import SimpleModel
+from spyne.model._base import (
+ Ignored,
+ ModelBase,
+ Null,
+ PushBase,
+ SimpleModel,
+)
# Primitives
from spyne.model.primitive import *
@@ -34,38 +37,29 @@
# store_as values
# it's sad that xml the pssm and xml the module conflict. that's why we need
# this after import of primitive package
-from spyne.model._base import xml
-from spyne.model._base import json
-from spyne.model._base import jsonb
-from spyne.model._base import table
-from spyne.model._base import msgpack
+from spyne.model._base import json, jsonb, msgpack, table, xml
# Classes
-from spyne.model.complex import ComplexModelMeta
-from spyne.model.complex import ComplexModelBase
-from spyne.model.complex import ComplexModel
-from spyne.model.complex import TTableModelBase
-from spyne.model.complex import TTableModel
-
-# Iterables
-from spyne.model.complex import Array
-from spyne.model.complex import Iterable
-from spyne.model.complex import PushBase
-
-# Modifiers
-from spyne.model.complex import Mandatory
-from spyne.model.complex import XmlAttribute
-from spyne.model.complex import XmlData
-
-# Markers
-from spyne.model.complex import SelfReference
-
-# Binary
-from spyne.model.binary import File
-from spyne.model.binary import ByteArray
+from spyne.model.complex import (
+ Array,
+ ComplexModel,
+ ComplexModelBase,
+ ComplexModelMeta,
+ Iterable,
+ Mandatory,
+ PushBase,
+ SelfReference,
+ TTableModel,
+ TTableModelBase,
+ XmlAttribute,
+ XmlData,
+)
# Enum
from spyne.model.enum import Enum
# Fault
-from spyne.model.fault import Fault
+from spyne.model.fault import Fault, ValidationError
+
+# Binary (must come last — depends on primitive, complex and fault being initialized)
+from spyne.model.binary import ByteArray, File
diff --git a/spyne/model/_base.py b/spyne/model/_base.py
index 2a4db3687..f418aafbe 100644
--- a/spyne/model/_base.py
+++ b/spyne/model/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -24,43 +23,47 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
-import re
import decimal
+import re
import threading
-
-import spyne.const.xml
-
-from copy import deepcopy
from collections import OrderedDict
+from copy import deepcopy
+import spyne.const.xml
from spyne import const
-from spyne.util import Break, six
+from spyne.const.xml import DEFAULT_NS
+from spyne.util import Break
from spyne.util.cdict import cdict
from spyne.util.odict import odict
-from spyne.const.xml import DEFAULT_NS
-
class Ignored(object):
"""When returned as a real rpc response, this is equivalent to returning
None. However, direct method invocations (and NullServer) get the return
value. It can be used for tests and from hooks."""
- __slots__ = ('args', 'kwargs')
+ __slots__ = ("args", "kwargs")
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
def __eq__(self, other):
- return isinstance(other, Ignored) \
- and self.args == other.args and self.kwargs == other.kwargs
+ return (
+ isinstance(other, Ignored)
+ and self.args == other.args
+ and self.kwargs == other.kwargs
+ )
def __ne__(self, other):
- return not (isinstance(other, Ignored) \
- and self.args == other.args and self.kwargs == other.kwargs)
+ return not (
+ isinstance(other, Ignored)
+ and self.args == other.args
+ and self.kwargs == other.kwargs
+ )
def _decode_pa_dict(d):
@@ -92,25 +95,24 @@ class AttributesMeta(type(object)):
def __new__(cls, cls_name, cls_bases, cls_dict):
# Mapper args should not be inherited.
- if not 'sqla_mapper_args' in cls_dict:
- cls_dict['sqla_mapper_args'] = None
+ if not "sqla_mapper_args" in cls_dict:
+ cls_dict["sqla_mapper_args"] = None
rd = {}
for k in list(cls_dict.keys()):
- if k in ('parser', 'cast'):
- rd['parser'] = cls_dict.pop(k)
+ if k in ("parser", "cast"):
+ rd["parser"] = cls_dict.pop(k)
continue
- if k in ('sanitize', 'sanitizer'):
- rd['sanitizer'] = cls_dict.pop(k)
+ if k in ("sanitize", "sanitizer"):
+ rd["sanitizer"] = cls_dict.pop(k)
continue
- if k == 'logged':
- rd['logged'] = cls_dict.pop(k)
+ if k == "logged":
+ rd["logged"] = cls_dict.pop(k)
continue
- retval = super(AttributesMeta, cls).__new__(cls, cls_name, cls_bases,
- cls_dict)
+ retval = super(AttributesMeta, cls).__new__(cls, cls_name, cls_bases, cls_dict)
for k, v in rd.items():
if v is None:
@@ -122,11 +124,11 @@ def __new__(cls, cls_name, cls_bases, cls_dict):
def __init__(self, cls_name, cls_bases, cls_dict):
# you will probably want to look at ModelBase._s_customize as well.
- if not hasattr(self, '_method_config_do'):
+ if not hasattr(self, "_method_config_do"):
self._method_config_do = None
- nullable = cls_dict.get('nullable', None)
- nillable = cls_dict.get('nillable', None)
+ nullable = cls_dict.get("nullable", None)
+ nillable = cls_dict.get("nillable", None)
if nullable is not None:
assert nillable is None or nullable == nillable
self._nullable = nullable
@@ -135,43 +137,40 @@ def __init__(self, cls_name, cls_bases, cls_dict):
assert nullable is None or nullable == nillable
self._nullable = nillable
- if not hasattr(self, '_nullable'):
+ if not hasattr(self, "_nullable"):
self._nullable = None
- if not hasattr(self, '_default_factory'):
+ if not hasattr(self, "_default_factory"):
self._default_factory = None
- if not hasattr(self, '_html_cloth'):
+ if not hasattr(self, "_html_cloth"):
self._html_cloth = None
- if not hasattr(self, '_html_root_cloth'):
+ if not hasattr(self, "_html_root_cloth"):
self._html_root_cloth = None
- if 'html_cloth' in cls_dict:
- self.set_html_cloth(cls_dict.pop('html_cloth'))
- if 'html_root_cloth' in cls_dict:
- self.set_html_cloth(cls_dict.pop('html_root_cloth'))
+ if "html_cloth" in cls_dict:
+ self.set_html_cloth(cls_dict.pop("html_cloth"))
+ if "html_root_cloth" in cls_dict:
+ self.set_html_cloth(cls_dict.pop("html_root_cloth"))
- if not hasattr(self, '_xml_cloth'):
+ if not hasattr(self, "_xml_cloth"):
self._xml_cloth = None
- if not hasattr(self, '_xml_root_cloth'):
+ if not hasattr(self, "_xml_root_cloth"):
self._xml_root_cloth = None
- if 'xml_cloth' in cls_dict:
- self.set_xml_cloth(cls_dict.pop('xml_cloth'))
+ if "xml_cloth" in cls_dict:
+ self.set_xml_cloth(cls_dict.pop("xml_cloth"))
- if 'xml_root_cloth' in cls_dict:
- self.set_xml_cloth(cls_dict.pop('xml_root_cloth'))
+ if "xml_root_cloth" in cls_dict:
+ self.set_xml_cloth(cls_dict.pop("xml_root_cloth"))
- if 'method_config_do' in cls_dict and \
- cls_dict['method_config_do'] is not None:
- cls_dict['method_config_do'] = \
- staticmethod(cls_dict['method_config_do'])
+ if "method_config_do" in cls_dict and cls_dict["method_config_do"] is not None:
+ cls_dict["method_config_do"] = staticmethod(cls_dict["method_config_do"])
super(AttributesMeta, self).__init__(cls_name, cls_bases, cls_dict)
def get_nullable(self):
- return (self._nullable if self._nullable is not None else
- self.NULLABLE_DEFAULT)
+ return self._nullable if self._nullable is not None else self.NULLABLE_DEFAULT
def set_nullable(self, what):
self._nullable = what
@@ -196,8 +195,10 @@ def set_default_factory(self, what):
def get_html_cloth(self):
return self._html_cloth
+
def set_html_cloth(self, what):
from spyne.protocol.cloth.to_cloth import ClothParserMixin
+
cm = ClothParserMixin.from_html_cloth(what)
if cm._root_cloth is not None:
self._html_root_cloth = cm._root_cloth
@@ -205,16 +206,20 @@ def set_html_cloth(self, what):
self._html_cloth = cm._cloth
else:
raise Exception("%r is not a suitable cloth", what)
+
html_cloth = property(get_html_cloth, set_html_cloth)
def get_html_root_cloth(self):
return self._html_root_cloth
+
html_root_cloth = property(get_html_root_cloth)
def get_xml_cloth(self):
return self._xml_cloth
+
def set_xml_cloth(self, what):
from spyne.protocol.cloth.to_cloth import ClothParserMixin
+
cm = ClothParserMixin.from_xml_cloth(what)
if cm._root_cloth is not None:
self._xml_root_cloth = cm._root_cloth
@@ -222,19 +227,23 @@ def set_xml_cloth(self, what):
self._xml_cloth = cm._cloth
else:
raise Exception("%r is not a suitable cloth", what)
+
xml_cloth = property(get_xml_cloth, set_xml_cloth)
def get_xml_root_cloth(self):
return self._xml_root_cloth
+
xml_root_cloth = property(get_xml_root_cloth)
def get_method_config_do(self):
return self._method_config_do
+
def set_method_config_do(self, what):
if what is None:
self._method_config_do = None
else:
self._method_config_do = staticmethod(what)
+
method_config_do = property(get_method_config_do, set_method_config_do)
@@ -251,8 +260,7 @@ def customize(self, **kwargs):
return type(cls_name, cls_bases, cls_dict)
-@six.add_metaclass(ModelBaseMeta)
-class ModelBase(object):
+class ModelBase(metaclass=ModelBaseMeta):
"""The base class for type markers. It defines the model interface for the
interface generators to use and also manages class customizations that are
mainly used for defining constraints on input values.
@@ -284,8 +292,7 @@ class ModelBase(object):
#
# Please note that min_occurs and max_occurs must be validated in the
# ComplexModelBase deserializer.
- @six.add_metaclass(AttributesMeta)
- class Attributes(object):
+ class Attributes(metaclass=AttributesMeta):
"""The class that holds the constraints for the given type."""
_wrapper = False
@@ -336,7 +343,7 @@ class Attributes(object):
will imply an iterable of objects as native python type. Can be set to
``decimal.Decimal("inf")`` for arbitrary number of arguments."""
- schema_tag = spyne.const.xml.XSD('element')
+ schema_tag = spyne.const.xml.XSD("element")
"""The tag used to add a primitives as child to a complex type in the
xml schema."""
@@ -485,7 +492,6 @@ class Attributes(object):
"""A dict of classes that override polymorphic substitions for classes
given as keys to classes given as values."""
-
class Annotations(object):
"""The class that holds the annotations for the given type."""
@@ -549,8 +555,9 @@ def _fill_empty_type_name(cls, parent_ns, parent_tn, k):
cls.__type_name__ = "%s_%s%s" % (parent_tn, k, const.TYPE_SUFFIX)
extends = cls.__extends__
while extends is not None and extends.__type_name__ is ModelBase.Empty:
- cls.__extends__._fill_empty_type_name(cls.get_namespace(),
- cls.get_type_name(), k + const.PARENT_SUFFIX)
+ cls.__extends__._fill_empty_type_name(
+ cls.get_namespace(), cls.get_type_name(), k + const.PARENT_SUFFIX
+ )
extends = extends.__extends__
# TODO: rename to "resolve_identifier"
@@ -570,19 +577,18 @@ def resolve_namespace(cls, default_ns, tags=None):
if cls.__namespace__ is spyne.const.xml.DEFAULT_NS:
cls.__namespace__ = default_ns
- if (cls.__namespace__ in spyne.const.xml.PREFMAP and
- not cls.is_default(cls)):
+ if cls.__namespace__ in spyne.const.xml.PREFMAP and not cls.is_default(cls):
cls.__namespace__ = default_ns
if cls.__namespace__ is None:
ret = []
- for f in cls.__module__.split('.'):
- if f.startswith('_'):
+ for f in cls.__module__.split("."):
+ if f.startswith("_"):
break
else:
ret.append(f)
- cls.__namespace__ = '.'.join(ret)
+ cls.__namespace__ = ".".join(ret)
if cls.__namespace__ is None or len(cls.__namespace__) == 0:
cls.__namespace__ = default_ns
@@ -592,15 +598,14 @@ def resolve_namespace(cls, default_ns, tags=None):
# print(" resolve ns for %r to %r" % (cls, cls.__namespace__))
- if getattr(cls, '__extends__', None) != None:
+ if getattr(cls, "__extends__", None) != None:
cls.__extends__.resolve_namespace(cls.__extends__, default_ns, tags)
return True
@classmethod
def get_type_name(cls):
- """Returns the class name unless the __type_name__ attribute is defined.
- """
+ """Returns the class name unless the __type_name__ attribute is defined."""
retval = cls.__type_name__
if retval is None:
@@ -611,12 +616,10 @@ def get_type_name(cls):
# FIXME: Rename this to get_type_name_with_ns_pref
@classmethod
def get_type_name_ns(cls, interface):
- """Returns the type name with a namespace prefix, separated by a column.
- """
+ """Returns the type name with a namespace prefix, separated by a column."""
if cls.get_namespace() != None:
- return "%s:%s" % (cls.get_namespace_prefix(interface),
- cls.get_type_name())
+ return "%s:%s" % (cls.get_namespace_prefix(interface), cls.get_type_name())
@classmethod
def get_element_name(cls):
@@ -640,14 +643,14 @@ def to_bytes(cls, value):
"""
Returns str(value). This should be overridden if this is not enough.
"""
- return six.binary_type(value)
+ return bytes(value)
@classmethod
def to_unicode(cls, value):
"""
Returns unicode(value). This should be overridden if this is not enough.
"""
- return six.text_type(value)
+ return str(value)
@classmethod
def get_documentation(cls):
@@ -656,7 +659,7 @@ def get_documentation(cls):
elif cls.Annotations.__use_parent_doc__:
return cls.__doc__
else:
- return ''
+ return ""
@classmethod
def _s_customize(cls, **kwargs):
@@ -667,12 +670,12 @@ def _s_customize(cls, **kwargs):
def _log_debug(s, *args):
logger.debug("\t%s: %s" % (cls.get_type_name(), s), *args)
- cls_dict = odict({'__module__': cls.__module__, '__doc__': cls.__doc__})
+ cls_dict = odict({"__module__": cls.__module__, "__doc__": cls.__doc__})
- if getattr(cls, '__orig__', None) is None:
- cls_dict['__orig__'] = cls
+ if getattr(cls, "__orig__", None) is None:
+ cls_dict["__orig__"] = cls
else:
- cls_dict['__orig__'] = cls.__orig__
+ cls_dict["__orig__"] = cls.__orig__
class Attributes(cls.Attributes):
_explicit_type_name = False
@@ -683,95 +686,106 @@ class Attributes(cls.Attributes):
if cls.Attributes.sqla_column_args is None:
Attributes.sqla_column_args = (), {}
else:
- Attributes.sqla_column_args = deepcopy(
- cls.Attributes.sqla_column_args)
+ Attributes.sqla_column_args = deepcopy(cls.Attributes.sqla_column_args)
- cls_dict['Attributes'] = Attributes
+ cls_dict["Attributes"] = Attributes
# properties get reset every time a new class is defined. So we need
# to reinitialize them explicitly.
- for k in ('nillable', '_xml_cloth', '_xml_root_cloth', '_html_cloth',
- '_html_root_cloth'):
+ for k in (
+ "nillable",
+ "_xml_cloth",
+ "_xml_root_cloth",
+ "_html_cloth",
+ "_html_root_cloth",
+ ):
v = getattr(cls.Attributes, k)
if v is not None:
setattr(Attributes, k, v)
class Annotations(cls.Annotations):
pass
- cls_dict['Annotations'] = Annotations
+
+ cls_dict["Annotations"] = Annotations
# get protocol attrs
- prot = kwargs.get('protocol', None)
+ prot = kwargs.get("protocol", None)
if prot is None:
- prot = kwargs.get('prot', None)
+ prot = kwargs.get("prot", None)
if prot is None:
- prot = kwargs.get('p', None)
+ prot = kwargs.get("p", None)
if prot is not None and len(prot.type_attrs) > 0:
# if there is a class customization from protocol, do it
type_attrs = prot.type_attrs.copy()
type_attrs.update(kwargs)
- _log_debug("kwargs %r => %r from prot typeattr %r",
- kwargs, type_attrs, prot.type_attrs)
+ _log_debug(
+ "kwargs %r => %r from prot typeattr %r",
+ kwargs,
+ type_attrs,
+ prot.type_attrs,
+ )
kwargs = type_attrs
# the ones that wrap values in staticmethod() should be added to
# AttributesMeta initializer
for k, v in kwargs.items():
- if k.startswith('_'):
+ if k.startswith("_"):
_log_debug("ignoring '%s' because of leading underscore", k)
continue
- if k in ('protocol', 'prot', 'p'):
+ if k in ("protocol", "prot", "p"):
Attributes.prot = v
_log_debug("setting prot=%r", v)
- elif k in ('voa', 'validate_on_assignment'):
+ elif k in ("voa", "validate_on_assignment"):
Attributes.validate_on_assignment = v
_log_debug("setting voa=%r", v)
- elif k in ('parser', 'in_cast'):
- setattr(Attributes, 'parser', staticmethod(v))
+ elif k in ("parser", "in_cast"):
+ setattr(Attributes, "parser", staticmethod(v))
_log_debug("setting %s=%r", k, v)
- elif k in ('sanitize', 'sanitizer', 'out_cast'):
- setattr(Attributes, 'sanitizer', staticmethod(v))
+ elif k in ("sanitize", "sanitizer", "out_cast"):
+ setattr(Attributes, "sanitizer", staticmethod(v))
_log_debug("setting %s=%r as sanitizer", k, v)
- elif k == 'logged':
- setattr(Attributes, 'logged', staticmethod(v))
+ elif k == "logged":
+ setattr(Attributes, "logged", staticmethod(v))
_log_debug("setting %s=%r as log sanitizer", k, v)
elif k in ("doc", "appinfo"):
setattr(Annotations, k, v)
_log_debug("setting Annotations.%s=%r", k, v)
- elif k in ('primary_key', 'pk'):
- setattr(Attributes, 'primary_key', v)
- Attributes.sqla_column_args[-1]['primary_key'] = v
+ elif k in ("primary_key", "pk"):
+ setattr(Attributes, "primary_key", v)
+ Attributes.sqla_column_args[-1]["primary_key"] = v
_log_debug("setting primary_key=%r", v)
- elif k in ('protocol_attrs', 'prot_attrs', 'pa'):
- setattr(Attributes, 'prot_attrs', _decode_pa_dict(v))
+ elif k in ("protocol_attrs", "prot_attrs", "pa"):
+ setattr(Attributes, "prot_attrs", _decode_pa_dict(v))
_log_debug("setting prot_attrs=%r", v)
- elif k in ('foreign_key', 'fk'):
+ elif k in ("foreign_key", "fk"):
from sqlalchemy.schema import ForeignKey
+
t, d = Attributes.sqla_column_args
fkt = (ForeignKey(v),)
new_v = (t + fkt, d)
Attributes.sqla_column_args = new_v
_log_debug("setting sqla_column_args=%r", new_v)
- elif k in ('autoincrement', 'onupdate', 'server_default'):
+ elif k in ("autoincrement", "onupdate", "server_default"):
Attributes.sqla_column_args[-1][k] = v
_log_debug("adding %s=%r to Attributes.sqla_column_args", k, v)
- elif k == 'values_dict':
- assert not 'values' in v, "`values` and `values_dict` can't be" \
- "specified at the same time"
+ elif k == "values_dict":
+ assert not "values" in v, (
+ "`values` and `values_dict` can't be" "specified at the same time"
+ )
if not isinstance(v, dict):
# our odict has one nasty implicit behaviour: setitem on
@@ -782,23 +796,27 @@ class Annotations(cls.Annotations):
Attributes.values = list(v.keys())
Attributes.values_dict = v
- _log_debug("setting values=%r, values_dict=%r",
- Attributes.values, Attributes.values_dict)
+ _log_debug(
+ "setting values=%r, values_dict=%r",
+ Attributes.values,
+ Attributes.values_dict,
+ )
- elif k == 'exc_table':
+ elif k == "exc_table":
Attributes.exc_table = v
Attributes.exc_db = v
_log_debug("setting exc_table=%r, exc_db=%r", v, v)
- elif k == 'max_occurs' and v in ('unbounded', 'inf', float('inf')):
- new_v = decimal.Decimal('inf')
+ elif k == "max_occurs" and v in ("unbounded", "inf", float("inf")):
+ new_v = decimal.Decimal("inf")
setattr(Attributes, k, new_v)
_log_debug("setting max_occurs=%r", new_v)
- elif k == 'type_name':
+ elif k == "type_name":
Attributes._explicit_type_name = True
- _log_debug("setting _explicit_type_name=True because "
- "we have 'type_name'")
+ _log_debug(
+ "setting _explicit_type_name=True because " "we have 'type_name'"
+ )
else:
setattr(Attributes, k, v)
@@ -812,7 +830,7 @@ def validate_string(cls, value):
string. This is called before converting the incoming string to the
native python value."""
- return (cls.Attributes.nillable or value is not None)
+ return cls.Attributes.nillable or value is not None
@staticmethod
def validate_native(cls, value):
@@ -820,7 +838,7 @@ def validate_native(cls, value):
value. This is called after converting the incoming string to the
native python value."""
- return (cls.Attributes.nullable or value is not None)
+ return cls.Attributes.nullable or value is not None
class Null(ModelBase):
@@ -829,9 +847,8 @@ class Null(ModelBase):
class SimpleModelAttributesMeta(AttributesMeta):
def __init__(self, cls_name, cls_bases, cls_dict):
- super(SimpleModelAttributesMeta, self).__init__(cls_name, cls_bases,
- cls_dict)
- if getattr(self, '_pattern', None) is None:
+ super(SimpleModelAttributesMeta, self).__init__(cls_name, cls_bases, cls_dict)
+ if getattr(self, "_pattern", None) is None:
self._pattern = None
def get_pattern(self):
@@ -861,8 +878,7 @@ class SimpleModel(ModelBase):
__namespace__ = "http://www.w3.org/2001/XMLSchema"
- @six.add_metaclass(SimpleModelAttributesMeta)
- class Attributes(ModelBase.Attributes):
+ class Attributes(ModelBase.Attributes, metaclass=SimpleModelAttributesMeta):
"""The class that holds the constraints for the given type."""
values = set()
@@ -897,29 +913,31 @@ def customize(cls, **kwargs):
if not retval.is_default(retval):
retval.__extends__ = cls
retval.__type_name__ = kwargs.get("type_name", ModelBase.Empty)
- if 'type_name' in kwargs:
- logger.debug("Type name for %r was overridden as '%s'",
- retval, retval.__type_name__)
+ if "type_name" in kwargs:
+ logger.debug(
+ "Type name for %r was overridden as '%s'",
+ retval,
+ retval.__type_name__,
+ )
- retval.resolve_namespace(retval, kwargs.get('__namespace__'))
+ retval.resolve_namespace(retval, kwargs.get("__namespace__"))
return retval
@staticmethod
def is_default(cls):
- return (cls.Attributes.values == SimpleModel.Attributes.values)
+ return cls.Attributes.values == SimpleModel.Attributes.values
@staticmethod
def validate_native(cls, value):
- return (ModelBase.validate_native(cls, value)
- and (
- cls.Attributes.values is None or
- len(cls.Attributes.values) == 0 or (
- (value is None and cls.Attributes.nillable) or
- (value is not None and value in cls.Attributes.values)
- )
- )
+ return ModelBase.validate_native(cls, value) and (
+ cls.Attributes.values is None
+ or len(cls.Attributes.values) == 0
+ or (
+ (value is None and cls.Attributes.nillable)
+ or (value is not None and value in cls.Attributes.values)
)
+ )
class PushBase(object):
@@ -1010,13 +1028,28 @@ class table:
:param back_populates: See https://docs.sqlalchemy.org/en/13/orm/relationship_api.html?highlight=lazy#sqlalchemy.orm.relationship.params.back_populates
"""
- def __init__(self, multi=False, left=None, right=None, backref=None,
- id_backref=None, cascade=False, lazy='select', back_populates=None,
- fk_left_deferrable=None, fk_left_initially=None,
- fk_right_deferrable=None, fk_right_initially=None,
- fk_left_ondelete=None, fk_left_onupdate=None,
- fk_right_ondelete=None, fk_right_onupdate=None,
- explicit_join=False, order_by=False, single_parent=None):
+ def __init__(
+ self,
+ multi=False,
+ left=None,
+ right=None,
+ backref=None,
+ id_backref=None,
+ cascade=False,
+ lazy="select",
+ back_populates=None,
+ fk_left_deferrable=None,
+ fk_left_initially=None,
+ fk_right_deferrable=None,
+ fk_right_initially=None,
+ fk_left_ondelete=None,
+ fk_left_onupdate=None,
+ fk_right_ondelete=None,
+ fk_right_onupdate=None,
+ explicit_join=False,
+ order_by=False,
+ single_parent=None,
+ ):
self.multi = multi
self.left = left
self.right = right
@@ -1070,21 +1103,31 @@ class msgpack:
Make sure you don't mix this with the msgpack package when importing.
"""
+
def __init__(self):
pass
-PSSM_VALUES = {'json': json, 'jsonb': jsonb, 'xml': xml,
- 'msgpack': msgpack, 'table': table}
+PSSM_VALUES = {
+ "json": json,
+ "jsonb": jsonb,
+ "xml": xml,
+ "msgpack": msgpack,
+ "table": table,
+}
def apply_pssm(val):
if val is not None:
val_c = PSSM_VALUES.get(val, None)
if val_c is None:
- assert isinstance(val, tuple(PSSM_VALUES.values())), \
- "'store_as' should be one of: %r or an instance of %r not %r" \
- % (tuple(PSSM_VALUES.keys()), tuple(PSSM_VALUES.values()), val)
+ assert isinstance(
+ val, tuple(PSSM_VALUES.values())
+ ), "'store_as' should be one of: %r or an instance of %r not %r" % (
+ tuple(PSSM_VALUES.keys()),
+ tuple(PSSM_VALUES.values()),
+ val,
+ )
return val
return val_c()
diff --git a/spyne/model/addtl.py b/spyne/model/addtl.py
index 6bc83cfc8..b031bb13c 100644
--- a/spyne/model/addtl.py
+++ b/spyne/model/addtl.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,8 +17,8 @@
#
import re
-from spyne import M, Boolean, DateTime, Date, Time, ComplexModel, \
- ValidationError
+
+from spyne import Boolean, ComplexModel, Date, DateTime, M, Time, ValidationError
from spyne.protocol import InProtocolBase
@@ -34,65 +33,57 @@ def from_string(cls, s):
print()
print(start_incl, start_str, end_str, end_incl)
- start_incl = (start_incl == '[')
- start = InProtocolBase().from_unicode(
- cls._type_info['start'], start_str)
- end = InProtocolBase().from_unicode(cls._type_info['start'], end_str)
- end_incl = (end_incl == ']')
+ start_incl = start_incl == "["
+ start = InProtocolBase().from_unicode(cls._type_info["start"], start_str)
+ end = InProtocolBase().from_unicode(cls._type_info["start"], end_str)
+ end_incl = end_incl == "]"
print(start_incl, start, end, end_incl)
- return cls(start_inclusive=start_incl, start=start, end=end,
- end_inclusive=end_incl)
+ return cls(
+ start_inclusive=start_incl, start=start, end=end, end_inclusive=end_incl
+ )
def to_string(self):
- return '[%s,%s]' % (self.start.isoformat(), self.end.isoformat())
+ return "[%s,%s]" % (self.start.isoformat(), self.end.isoformat())
class DateTimeSegment(ComplexModel, SegmentBase):
_SEGMENT_RE = re.compile(
- u"([\\[\\]])"
- u"([0-9:\\.T-]+)"
- u","
- u"([0-9:\\.T-]+)"
- u"([\\[\\]])", re.DEBUG | re.UNICODE)
+ "([\\[\\]])" "([0-9:\\.T-]+)" "," "([0-9:\\.T-]+)" "([\\[\\]])",
+ re.DEBUG | re.UNICODE,
+ )
_type_info = [
- ('start_inclusive', M(Boolean(default=True))),
- ('start', M(DateTime)),
- ('end', M(DateTime)),
- ('end_inclusive', M(Boolean(default=True))),
+ ("start_inclusive", M(Boolean(default=True))),
+ ("start", M(DateTime)),
+ ("end", M(DateTime)),
+ ("end_inclusive", M(Boolean(default=True))),
]
-
class DateSegment(ComplexModel, SegmentBase):
_SEGMENT_RE = re.compile(
- u"([\\[\\]])"
- u"([0-9-]+)"
- u","
- u"([0-9-]+)"
- u"([\\[\\]])", re.DEBUG | re.UNICODE)
+ "([\\[\\]])" "([0-9-]+)" "," "([0-9-]+)" "([\\[\\]])", re.DEBUG | re.UNICODE
+ )
_type_info = [
- ('start_inclusive', M(Boolean(default=True))),
- ('start', M(Date)),
- ('end', M(Date)),
- ('end_inclusive', M(Boolean(default=True))),
+ ("start_inclusive", M(Boolean(default=True))),
+ ("start", M(Date)),
+ ("end", M(Date)),
+ ("end_inclusive", M(Boolean(default=True))),
]
class TimeSegment(ComplexModel, SegmentBase):
_SEGMENT_RE = re.compile(
- u"([\\[\\]])"
- u"([0-9:\\.]+)"
- u","
- u"([0-9:\\.]+)"
- u"([\\[\\]])", re.DEBUG | re.UNICODE)
+ "([\\[\\]])" "([0-9:\\.]+)" "," "([0-9:\\.]+)" "([\\[\\]])",
+ re.DEBUG | re.UNICODE,
+ )
_type_info = [
- ('start_inclusive', M(Boolean(default=True))),
- ('start', M(Time)),
- ('end', M(Time)),
- ('end_inclusive', M(Boolean(default=True))),
+ ("start_inclusive", M(Boolean(default=True))),
+ ("start", M(Time)),
+ ("end", M(Time)),
+ ("end_inclusive", M(Boolean(default=True))),
]
diff --git a/spyne/model/binary.py b/spyne/model/binary.py
index 4bc446d9f..640169ba6 100644
--- a/spyne/model/binary.py
+++ b/spyne/model/binary.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,34 +17,44 @@
#
"""The ``spyne.model.binary`` package contains binary type markers."""
+
+# isort: skip_file
+
import logging
+
logger = logging.getLogger(__name__)
-import os
import base64
-import tempfile
import errno
+import os
+import tempfile
+from base64 import b64decode, b64encode, urlsafe_b64decode, urlsafe_b64encode
+from binascii import hexlify, unhexlify
+from io import BytesIO, StringIO
+from mmap import ACCESS_READ
+from mmap import error as MmapError
+from mmap import mmap
+from os.path import abspath, basename, isdir, isfile
+
+from spyne.model.fault import ValidationError
+from spyne.model import ComplexModel, SimpleModel, Unicode
+from spyne.util import _bytes_join
-from mmap import mmap, ACCESS_READ, error as MmapError
-from base64 import b64encode
-from base64 import b64decode
-from base64 import urlsafe_b64encode
-from base64 import urlsafe_b64decode
-from binascii import hexlify
-from binascii import unhexlify
-from os.path import abspath, isdir, isfile, basename
-from spyne.error import ValidationError
-from spyne.util import _bytes_join
-from spyne.model import ComplexModel, Unicode
-from spyne.model import SimpleModel
-from spyne.util import six
-from spyne.util.six import BytesIO, StringIO
+class BINARY_ENCODING_HEX:
+ pass
+
+
+class BINARY_ENCODING_BASE64:
+ pass
-class BINARY_ENCODING_HEX: pass
-class BINARY_ENCODING_BASE64: pass
-class BINARY_ENCODING_USE_DEFAULT: pass
-class BINARY_ENCODING_URLSAFE_BASE64: pass
+
+class BINARY_ENCODING_USE_DEFAULT:
+ pass
+
+
+class BINARY_ENCODING_URLSAFE_BASE64:
+ pass
class ByteArray(SimpleModel):
@@ -57,7 +66,7 @@ class ByteArray(SimpleModel):
and a sequence of ``bytes`` objects for Python 3.x.
"""
- __type_name__ = 'base64Binary'
+ __type_name__ = "base64Binary"
__namespace__ = "http://www.w3.org/2001/XMLSchema"
class Attributes(SimpleModel.Attributes):
@@ -70,31 +79,33 @@ class Attributes(SimpleModel.Attributes):
def __new__(cls, **kwargs):
tn = None
- if 'encoding' in kwargs:
- v = kwargs['encoding']
+ if "encoding" in kwargs:
+ v = kwargs["encoding"]
if v is None:
- kwargs['encoding'] = BINARY_ENCODING_USE_DEFAULT
+ kwargs["encoding"] = BINARY_ENCODING_USE_DEFAULT
- elif v in ('base64', 'base64Binary', BINARY_ENCODING_BASE64):
+ elif v in ("base64", "base64Binary", BINARY_ENCODING_BASE64):
# This string is defined in the Xml Schema Standard
- tn = 'base64Binary'
- kwargs['encoding'] = BINARY_ENCODING_BASE64
+ tn = "base64Binary"
+ kwargs["encoding"] = BINARY_ENCODING_BASE64
- elif v in ('urlsafe_base64', BINARY_ENCODING_URLSAFE_BASE64):
+ elif v in ("urlsafe_base64", BINARY_ENCODING_URLSAFE_BASE64):
# the Xml Schema Standard does not define urlsafe base64
# FIXME: produce a regexp that validates urlsafe base64 strings
- tn = 'string'
- kwargs['encoding'] = BINARY_ENCODING_URLSAFE_BASE64
+ tn = "string"
+ kwargs["encoding"] = BINARY_ENCODING_URLSAFE_BASE64
- elif v in ('hex', 'hexBinary', BINARY_ENCODING_HEX):
+ elif v in ("hex", "hexBinary", BINARY_ENCODING_HEX):
# This string is defined in the Xml Schema Standard
- tn = 'hexBinary'
- kwargs['encoding'] = BINARY_ENCODING_HEX
+ tn = "hexBinary"
+ kwargs["encoding"] = BINARY_ENCODING_HEX
else:
- raise ValueError("'encoding' must be one of: %r" % \
- (tuple(ByteArray._encoding.handlers.values()),))
+ raise ValueError(
+ "'encoding' must be one of: %r"
+ % (tuple(ByteArray._encoding.handlers.values()),)
+ )
retval = cls.customize(**kwargs)
if tn is not None:
@@ -111,10 +122,10 @@ def to_base64(cls, value):
# TODO: be smarter about this
return b64encode(value[0])
- if isinstance(value, (six.binary_type, memoryview, mmap)):
+ if isinstance(value, (bytes, memoryview, mmap)):
return b64encode(value)
- return b64encode(b''.join(value))
+ return b64encode(b"".join(value))
@classmethod
def from_base64(cls, value):
@@ -133,9 +144,9 @@ def to_urlsafe_base64(cls, value):
@classmethod
def from_urlsafe_base64(cls, value):
- #FIXME: Find out why we need to do this.
- if isinstance(value, six.text_type):
- value = value.encode('utf8')
+ # FIXME: Find out why we need to do this.
+ if isinstance(value, str):
+ value = value.encode("utf8")
try:
if isinstance(value, (list, tuple)):
return (urlsafe_b64decode(_bytes_join(value)),)
@@ -160,16 +171,16 @@ def from_hex(cls, value):
def _default_binary_encoding(b):
- if isinstance(b, (six.binary_type, memoryview)):
+ if isinstance(b, (bytes, memoryview)):
return b
if isinstance(b, tuple) and len(b) > 0 and isinstance(b[0], mmap):
return b[0]
- if isinstance(b, six.text_type):
+ if isinstance(b, str):
raise ValueError(b)
- return b''.join(b)
+ return b"".join(b)
binary_encoding_handlers = {
@@ -188,7 +199,7 @@ def _default_binary_encoding(b):
class HybridFileStore(object):
- def __init__(self, store_path, db_format='json', type=None):
+ def __init__(self, store_path, db_format="json", type=None):
"""Marker to be passed to File's store_as to denote a hybrid
Sql/Filesystem storage scheme.
@@ -208,14 +219,13 @@ def __init__(self, store_path, db_format='json', type=None):
assert isdir(self.store)
-_BINARY = type('FileTypeBinary', (object,), {})
-_TEXT = type('FileTypeText', (object,), {})
+_BINARY = type("FileTypeBinary", (object,), {})
+_TEXT = type("FileTypeText", (object,), {})
class SanitizationError(ValidationError):
def __init__(self, obj):
- super(SanitizationError, self).__init__(
- obj, "%r was not sanitized before use")
+ super(SanitizationError, self).__init__(obj, "%r was not sanitized before use")
class _FileValue(ComplexModel):
@@ -226,26 +236,37 @@ class _FileValue(ComplexModel):
:param data: Optional sequence of ``str`` or ``bytes`` instances
that contain the file's data.
"""
+
# ^ This is the public docstring.
__type_name__ = "FileValue"
_type_info = [
- ('name', Unicode(encoding='utf8')),
- ('type', Unicode),
- ('data', ByteArray(logged='len')),
+ ("name", Unicode(encoding="utf8")),
+ ("type", Unicode),
+ ("data", ByteArray(logged="len")),
]
- def __init__(self, name=None, path=None, type='application/octet-stream',
- data=None, handle=None, move=False, _sanitize=True):
+ def __init__(
+ self,
+ name=None,
+ path=None,
+ type="application/octet-stream",
+ data=None,
+ handle=None,
+ move=False,
+ _sanitize=True,
+ ):
self.name = name
"""The file basename, no directory information here."""
if self.name is not None and _sanitize:
if not os.path.basename(self.name) == self.name:
- raise ValidationError(self.name,
- "File name %r should not contain any directory information")
+ raise ValidationError(
+ self.name,
+ "File name %r should not contain any directory information",
+ )
self.sanitized = _sanitize
@@ -291,7 +312,7 @@ def rollover(self):
self.abspath = self.path = self.handle.name
self.name = basename(self.abspath)
else:
- self.handle = open(self.path, 'wb')
+ self.handle = open(self.path, "wb")
# FIXME: abspath could be None here, how do we make sure it's
# the right value?
@@ -309,9 +330,7 @@ def rollover(self):
except MmapError as e:
if e.errno == errno.EACCES:
- self.data = (
- mmap(self.handle.fileno(), 0, access=ACCESS_READ),
- )
+ self.data = (mmap(self.handle.fileno(), 0, access=ACCESS_READ),)
else:
raise
@@ -319,14 +338,16 @@ def rollover(self):
if not isfile(self.path):
logger.error("File path in %r not found", self)
- self.handle = open(self.path, 'rb')
+ self.handle = open(self.path, "rb")
self.data = (mmap(self.handle.fileno(), 0, access=ACCESS_READ),)
self.abspath = abspath(self.path)
self.name = self.path = basename(self.path)
else:
- raise ValueError("Invalid file object passed in. All of "
- ".data, .handle and .path are None.")
+ raise ValueError(
+ "Invalid file object passed in. All of "
+ ".data, .handle and .path are None."
+ )
class File(SimpleModel):
@@ -334,7 +355,7 @@ class File(SimpleModel):
standard way of encoding file metadata along with binary data. (E.g. Http)
"""
- __type_name__ = 'base64Binary'
+ __type_name__ = "base64Binary"
__namespace__ = "http://www.w3.org/2001/XMLSchema"
BINARY = _BINARY
@@ -366,12 +387,14 @@ def to_base64(cls, value):
if value is None:
return
- assert value.path, "You need to write data to persistent storage first " \
- "if you want to read it back."
- f = open(value.path, 'rb')
+ assert value.path, (
+ "You need to write data to persistent storage first "
+ "if you want to read it back."
+ )
+ f = open(value.path, "rb")
# base64 encodes every 3 bytes to 4 base64 characters
- data = f.read(0x4001) # so this needs to be a multiple of 3
+ data = f.read(0x4001) # so this needs to be a multiple of 3
while len(data) > 0:
yield base64.b64encode(data)
data = f.read(0x4001)
@@ -385,8 +408,12 @@ def from_base64(cls, value):
return File.Value(data=[base64.b64decode(value)])
def __repr__(self):
- return "File(name=%r, path=%r, type=%r, data=%r)" % \
- (self.name, self.path, self.type, self.data)
+ return "File(name=%r, path=%r, type=%r, data=%r)" % (
+ self.name,
+ self.path,
+ self.type,
+ self.data,
+ )
@classmethod
def store_as(cls, what):
diff --git a/spyne/model/complex.py b/spyne/model/complex.py
index a6580abb1..bd937d03c 100644
--- a/spyne/model/complex.py
+++ b/spyne/model/complex.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -26,46 +25,52 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
import decimal
import traceback
-
+from collections import OrderedDict, deque
from copy import copy
-from weakref import WeakKeyDictionary
-from collections import deque, OrderedDict
from inspect import isclass
from itertools import chain
+from weakref import WeakKeyDictionary
from spyne import const
from spyne.const.xml import PREFMAP
-from spyne.model import Point, Unicode, PushBase, ModelBase
+# FIXME: for backwards compatibility, to be removed in Spyne 3
+# noinspection PyUnresolvedReferences
+from spyne.model import (
+ ModelBase,
+ Point,
+ PushBase,
+ Unicode,
+ json,
+ jsonb,
+ msgpack,
+ table,
+ xml,
+)
from spyne.model._base import PSSM_VALUES, apply_pssm
from spyne.model.primitive import NATIVE_MAP
from spyne.model.primitive._base import AnyXml
-
-from spyne.util import six, memoize, memoize_id, sanitize_args, \
- memoize_ignore_none
+from spyne.util import memoize, memoize_id, memoize_ignore_none, sanitize_args
from spyne.util.color import YEL
from spyne.util.meta import Prepareable
from spyne.util.odict import odict
-from spyne.util.six import add_metaclass, with_metaclass, string_types
-
-# FIXME: for backwards compatibility, to be removed in Spyne 3
-# noinspection PyUnresolvedReferences
-from spyne.model import json, jsonb, xml, msgpack, table
def _get_flat_type_info(cls, retval):
assert isinstance(retval, TypeInfo)
- parent = getattr(cls, '__extends__', None)
+ parent = getattr(cls, "__extends__", None)
if not (parent is None):
_get_flat_type_info(parent, retval)
retval.update(cls._type_info)
retval.alt.update(cls._type_info_alt) # FIXME: move to cls._type_info.alt
- retval.attrs.update({k: v for (k, v) in cls._type_info.items()
- if issubclass(v, XmlAttribute)})
+ retval.attrs.update(
+ {k: v for (k, v) in cls._type_info.items() if issubclass(v, XmlAttribute)}
+ )
return retval
@@ -78,12 +83,12 @@ def __init__(self, *args, **kwargs):
self.attrs = OrderedDict()
def __setitem__(self, key, val):
- assert isinstance(key, string_types)
+ assert isinstance(key, str)
super(TypeInfo, self).__setitem__(key, val)
class _SimpleTypeInfoElement(object):
- __slots__ = ['path', 'parent', 'type', 'is_array', 'can_be_empty']
+ __slots__ = ["path", "parent", "type", "is_array", "can_be_empty"]
def __init__(self, path, parent, type_, is_array, can_be_empty):
self.path = path
@@ -93,8 +98,12 @@ def __init__(self, path, parent, type_, is_array, can_be_empty):
self.can_be_empty = can_be_empty
def __repr__(self):
- return "SimpleTypeInfoElement(path=%r, parent=%r, type=%r, is_array=%r)" \
- % (self.path, self.parent, self.type, self.is_array)
+ return "SimpleTypeInfoElement(path=%r, parent=%r, type=%r, is_array=%r)" % (
+ self.path,
+ self.parent,
+ self.type,
+ self.is_array,
+ )
class XmlModifier(ModelBase):
@@ -128,13 +137,11 @@ def _fill_empty_type_name(cls, parent_ns, parent_tn, k):
child_v.__type_name__ = tn
cls._type_info = TypeInfo({tn: child_v})
- cls.__type_name__ = '%s%s%s' % (const.ARRAY_PREFIX, tn,
- const.ARRAY_SUFFIX)
+ cls.__type_name__ = "%s%s%s" % (const.ARRAY_PREFIX, tn, const.ARRAY_SUFFIX)
extends = child_v.__extends__
while extends is not None and extends.get_type_name() is cls.Empty:
- extends._fill_empty_type_name(parent_ns, parent_tn,
- k + const.PARENT_SUFFIX)
+ extends._fill_empty_type_name(parent_ns, parent_tn, k + const.PARENT_SUFFIX)
extends = extends.__extends__
@@ -180,7 +187,7 @@ def __new__(cls, type_, use=None, ns=None):
retval = super(XmlAttribute, cls).__new__(cls, type_, ns)
retval._use = use
if retval.type.Attributes.min_occurs > 0 and retval._use is None:
- retval._use = 'required'
+ retval._use = "required"
return retval
@@ -192,15 +199,16 @@ def __init__(self, ref, use=None):
self._use = use
def describe(self, name, element, app):
- element.set('ref', self._ref)
+ element.set("ref", self._ref)
if self._use:
- element.set('use', self._use)
+ element.set("use", self._use)
class SelfReference(object):
"""Use this as a placeholder type in classes that contain themselves. See
:func:`spyne.test.model.test_complex.TestComplexModel.test_self_reference`.
"""
+
customize_args = []
customize_kwargs = {}
__orig__ = None
@@ -215,10 +223,14 @@ def customize(cls, *args, **kwargs):
if cls.__orig__ is None:
cls.__orig__ = cls
- return type("SelfReference", (cls,), {
- 'customize_args': args,
- 'customize_kwargs': kwargs,
- })
+ return type(
+ "SelfReference",
+ (cls,),
+ {
+ "customize_args": args,
+ "customize_kwargs": kwargs,
+ },
+ )
def _get_spyne_type(cls_name, k, v):
@@ -234,7 +246,7 @@ def _get_spyne_type(cls_name, k, v):
if subc:
if issubclass(v, Array) and len(v._type_info) != 1:
- raise Exception("Invalid Array definition in %s.%s."% (cls_name, k))
+ raise Exception("Invalid Array definition in %s.%s." % (cls_name, k))
elif issubclass(v, Point) and v.Attributes.dim is None:
raise Exception("Please specify the number of dimensions")
return v
@@ -256,13 +268,15 @@ def _join_args(x, y):
def _gen_attrs(cls_bases, cls_dict):
- attrs = cls_dict.get('Attributes', None)
+ attrs = cls_dict.get("Attributes", None)
if attrs is None:
for b in cls_bases:
- if hasattr(b, 'Attributes'):
+ if hasattr(b, "Attributes"):
+
class Attributes(b.Attributes):
pass
- attrs = cls_dict['Attributes'] = Attributes
+
+ attrs = cls_dict["Attributes"] = Attributes
break
else:
raise Exception("No ModelBase subclass in bases? Huh?")
@@ -273,7 +287,7 @@ class Attributes(b.Attributes):
def _get_type_info(cls, cls_name, cls_bases, cls_dict, attrs):
base_type_info = TypeInfo()
mixin = TypeInfo()
- extends = cls_dict.get('__extends__', None)
+ extends = cls_dict.get("__extends__", None)
# user did not specify explicit base class so let's try to derive it from
# the actual class hierarchy
@@ -281,7 +295,7 @@ def _get_type_info(cls, cls_name, cls_bases, cls_dict, attrs):
# we don't want origs end up as base classes
orig = cls_dict.get("__orig__", None)
if orig is None:
- orig = getattr(cls, '__orig__', None)
+ orig = getattr(cls, "__orig__", None)
if orig is not None:
bases = orig.__bases__
@@ -298,42 +312,55 @@ def _get_type_info(cls, cls_name, cls_bases, cls_dict, attrs):
continue
# mixins are simple
- if getattr(b, '__mixin__', False) == True:
+ if getattr(b, "__mixin__", False) == True:
logger.debug("Adding fields from mixin %r to '%s'", b, cls_name)
mixin.update(b.get_flat_type_info(b))
- if '__mixin__' not in cls_dict:
- cls_dict['__mixin__'] = False
+ if "__mixin__" not in cls_dict:
+ cls_dict["__mixin__"] = False
continue
if not (extends in (None, b)):
- raise Exception("Spyne objects do not support multiple "
+ raise Exception(
+ "Spyne objects do not support multiple "
"inheritance. Use mixins if you need to reuse "
- "fields from multiple classes.")
+ "fields from multiple classes."
+ )
if len(base_types) > 0 and issubclass(b, ModelBase):
extends = cls_dict["__extends__"] = b
- assert extends.__orig__ is None, "You can't inherit from a " \
- "customized class. You should first get your class " \
+ assert extends.__orig__ is None, (
+ "You can't inherit from a "
+ "customized class. You should first get your class "
"hierarchy right, then start customizing classes."
+ )
b.get_subclasses.memo.clear()
logger.debug("Registering %r as base of '%s'", b, cls_name)
- if not ('_type_info' in cls_dict):
- cls_dict['_type_info'] = _type_info = TypeInfo()
+ if not ("_type_info" in cls_dict):
+ cls_dict["_type_info"] = _type_info = TypeInfo()
_type_info.update(base_type_info)
class_fields = []
for k, v in cls_dict.items():
- if k.startswith('_'):
+ if k.startswith("_"):
continue
- if isinstance(v, tuple) and len(v) == 1 and \
- _get_spyne_type(cls_name, k, v[0]) is not None:
- logger.warning(YEL("There seems to be a stray comma in the"
- "definition of '%s.%s'.", cls_name, k))
+ if (
+ isinstance(v, tuple)
+ and len(v) == 1
+ and _get_spyne_type(cls_name, k, v[0]) is not None
+ ):
+ logger.warning(
+ YEL(
+ "There seems to be a stray comma in the"
+ "definition of '%s.%s'.",
+ cls_name,
+ k,
+ )
+ )
v = _get_spyne_type(cls_name, k, v)
@@ -345,10 +372,10 @@ def _get_type_info(cls, cls_name, cls_bases, cls_dict, attrs):
_type_info.update(class_fields)
else:
- _type_info = cls_dict['_type_info']
+ _type_info = cls_dict["_type_info"]
if not isinstance(_type_info, TypeInfo):
- _type_info = cls_dict['_type_info'] = TypeInfo(_type_info)
+ _type_info = cls_dict["_type_info"] = TypeInfo(_type_info)
for k, v in reversed(mixin.items()):
_type_info.insert(0, (k, v))
@@ -366,7 +393,7 @@ def __init__(self, *args, **kwargs):
def _gen_methods(cls, cls_dict):
methods = _MethodsDict()
for k, v in cls_dict.items():
- if not k.startswith('_') and hasattr(v, '_is_rpc'):
+ if not k.startswith("_") and hasattr(v, "_is_rpc"):
logger.debug("Registering %s as member method for %r", k, cls)
assert cls is not None
@@ -390,15 +417,14 @@ def _get_ordered_attributes(cls_name, cls_dict, attrs):
# FIXME: Maybe add a warning here?
return cls_dict
- SUPPORTED_ORDERS = ('random', 'declared')
- if (attrs.declare_order is not None and
- not attrs.declare_order in SUPPORTED_ORDERS):
+ SUPPORTED_ORDERS = ("random", "declared")
+ if attrs.declare_order is not None and not attrs.declare_order in SUPPORTED_ORDERS:
msg = "The declare_order attribute value %r is invalid in %s"
raise Exception(msg % (attrs.declare_order, cls_name))
declare_order = attrs.declare_order or const.DEFAULT_DECLARE_ORDER
- if declare_order is None or declare_order == 'random':
+ if declare_order is None or declare_order == "random":
# support old behaviour
cls_dict = dict(cls_dict)
@@ -406,22 +432,22 @@ def _get_ordered_attributes(cls_name, cls_dict, attrs):
def _sanitize_sqlalchemy_parameters(cls_dict, attrs):
- table_name = cls_dict.get('__tablename__', None)
+ table_name = cls_dict.get("__tablename__", None)
if attrs.table_name is None:
attrs.table_name = table_name
- _cls_table = cls_dict.get('__table__', None)
+ _cls_table = cls_dict.get("__table__", None)
if attrs.sqla_table is None:
attrs.sqla_table = _cls_table
- metadata = cls_dict.get('__metadata__', None)
+ metadata = cls_dict.get("__metadata__", None)
if attrs.sqla_metadata is None:
attrs.sqla_metadata = metadata
- margs = cls_dict.get('__mapper_args__', None)
+ margs = cls_dict.get("__mapper_args__", None)
attrs.sqla_mapper_args = _join_args(attrs.sqla_mapper_args, margs)
- targs = cls_dict.get('__table_args__', None)
+ targs = cls_dict.get("__table_args__", None)
attrs.sqla_table_args = _join_args(attrs.sqla_table_args, targs)
@@ -429,7 +455,7 @@ def _sanitize_type_info(cls_name, _type_info, _type_info_alt):
"""Make sure _type_info contents are sane"""
for k, v in _type_info.items():
- if not isinstance(k, six.string_types):
+ if not isinstance(k, str):
raise ValueError("Invalid class key", k)
if not isclass(v):
@@ -441,12 +467,11 @@ def _sanitize_type_info(cls_name, _type_info, _type_info_alt):
elif not issubclass(v, ModelBase):
v = _get_spyne_type(cls_name, k, v)
if v is None:
- raise ValueError( (cls_name, k, v) )
+ raise ValueError((cls_name, k, v))
_type_info[k] = v
elif issubclass(v, Array) and len(v._type_info) != 1:
- raise Exception("Invalid Array definition in %s.%s." %
- (cls_name, k))
+ raise Exception("Invalid Array definition in %s.%s." % (cls_name, k))
sub_ns = v.Attributes.sub_ns
sub_name = v.Attributes.sub_name
@@ -456,22 +481,19 @@ def _sanitize_type_info(cls_name, _type_info, _type_info_alt):
elif sub_ns is not None and sub_name is not None:
key = "{%s}%s" % (sub_ns, sub_name)
if key in _type_info:
- raise Exception("%r is already defined: %r" %
- (key, _type_info[key]))
+ raise Exception("%r is already defined: %r" % (key, _type_info[key]))
_type_info_alt[key] = v, k
elif sub_ns is None:
key = sub_name
if sub_ns in _type_info:
- raise Exception("%r is already defined: %r" %
- (key, _type_info[key]))
+ raise Exception("%r is already defined: %r" % (key, _type_info[key]))
_type_info_alt[key] = v, k
elif sub_name is None:
key = "{%s}%s" % (sub_ns, k)
if key in _type_info:
- raise Exception("%r is already defined: %r" %
- (key, _type_info[key]))
+ raise Exception("%r is already defined: %r" % (key, _type_info[key]))
_type_info_alt[key] = v, k
@@ -479,9 +501,9 @@ def _sanitize_type_info(cls_name, _type_info, _type_info_alt):
def _process_child_attrs(cls, retval, kwargs):
- child_attrs = copy(kwargs.get('child_attrs', None))
- child_attrs_all = kwargs.get('child_attrs_all', None)
- child_attrs_noexc = copy(kwargs.get('child_attrs_noexc', None))
+ child_attrs = copy(kwargs.get("child_attrs", None))
+ child_attrs_all = kwargs.get("child_attrs_all", None)
+ child_attrs_noexc = copy(kwargs.get("child_attrs_noexc", None))
# add exc=False to child_attrs_noexc
if child_attrs_noexc is not None:
@@ -491,19 +513,23 @@ def _process_child_attrs(cls, retval, kwargs):
child_attrs_all = D_EXC
else:
- if 'exc' in child_attrs_all and child_attrs_all['exc'] != D_EXC:
- logger.warning("Overriding child_attrs_all['exc'] to True "
- "for %r", cls)
+ if "exc" in child_attrs_all and child_attrs_all["exc"] != D_EXC:
+ logger.warning(
+ "Overriding child_attrs_all['exc'] to True " "for %r", cls
+ )
child_attrs_all.update(D_EXC)
# update child_attrs_noexc with exc=False
for k, v in child_attrs_noexc.items():
- if 'exc' in v:
- logger.warning("Overriding 'exc' for %s.%s from "
- "child_attrs_noexc with False", cls.get_type_name(), k)
+ if "exc" in v:
+ logger.warning(
+ "Overriding 'exc' for %s.%s from " "child_attrs_noexc with False",
+ cls.get_type_name(),
+ k,
+ )
- v['exc'] = False
+ v["exc"] = False
# update child_attrs with data from child_attrs_noexc
if child_attrs is None:
@@ -516,8 +542,11 @@ def _process_child_attrs(cls, retval, kwargs):
for k, v in child_attrs_noexc.items():
if k in child_attrs:
- logger.warning("Overriding child_attrs for %s.%s from "
- "child_attrs_noexc", cls.get_type_name(), k)
+ logger.warning(
+ "Overriding child_attrs for %s.%s from " "child_attrs_noexc",
+ cls.get_type_name(),
+ k,
+ )
child_attrs[k] = v
@@ -530,7 +559,8 @@ def _process_child_attrs(cls, retval, kwargs):
if retval.__extends__ is not None:
retval.__extends__ = retval.__extends__.customize(
- child_attrs_all=child_attrs_all)
+ child_attrs_all=child_attrs_all
+ )
retval.Attributes._delayed_child_attrs_all = child_attrs_all
@@ -545,8 +575,7 @@ def _process_child_attrs(cls, retval, kwargs):
base_fti = {}
if retval.__extends__ is not None:
- retval.__extends__ = retval.__extends__.customize(
- child_attrs=child_attrs)
+ retval.__extends__ = retval.__extends__.customize(child_attrs=child_attrs)
base_fti = retval.__extends__.get_flat_type_info(retval.__extends__)
for k, v in child_attrs.items():
@@ -557,10 +586,13 @@ def _process_child_attrs(cls, retval, kwargs):
def recust_selfref(selfref, cls):
if len(selfref.customize_args) > 0 or len(selfref.customize_kwargs) > 0:
- logger.debug("Replace self reference with %r with *%r and **%r",
- cls, selfref.customize_args, selfref.customize_kwargs)
- return cls.customize(*selfref.customize_args,
- **selfref.customize_kwargs)
+ logger.debug(
+ "Replace self reference with %r with *%r and **%r",
+ cls,
+ selfref.customize_args,
+ selfref.customize_kwargs,
+ )
+ return cls.customize(*selfref.customize_args, **selfref.customize_kwargs)
logger.debug("Replace self reference with %r", cls)
return cls
@@ -573,10 +605,6 @@ def _set_member_default(inst, key, cls, attr):
return False
if def_fac is not None:
- if six.PY2 and hasattr(def_fac, 'im_func'):
- # unbound-method error workaround. huh.
- def_fac = def_fac.im_func
-
dval = def_fac()
# should not check for read-only for default values
@@ -595,14 +623,13 @@ def _set_member_default(inst, key, cls, attr):
def _is_sqla_array(cls, attr):
# inner object is complex
- ret1 = issubclass(cls, Array) and \
- hasattr(cls.get_inner_type(), '_sa_class_manager')
+ ret1 = issubclass(cls, Array) and hasattr(cls.get_inner_type(), "_sa_class_manager")
# inner object is primitive
ret2 = issubclass(cls, Array) and attr.store_as is not None
# object is a bare array
- ret3 = attr.max_occurs > 1 and hasattr(cls, '_sa_class_manager')
+ ret3 = attr.max_occurs > 1 and hasattr(cls, "_sa_class_manager")
return ret1 or ret2 or ret3
@@ -614,7 +641,7 @@ def _init_member(inst, key, cls, attr):
return # we skip read-only properties
if _set_member_default(inst, key, cls, attr):
- return
+ return
# sqlalchemy objects do their own init.
if _is_sqla_array(cls, attr):
@@ -628,7 +655,7 @@ def _init_member(inst, key, cls, attr):
return
# sqlalchemy objects do their own init.
- if hasattr(inst.__class__, '_sa_class_manager'):
+ if hasattr(inst.__class__, "_sa_class_manager"):
# except the attributes that sqlalchemy doesn't know about
if attr.exc_db:
setattr(inst, key, None)
@@ -641,7 +668,7 @@ def _init_member(inst, key, cls, attr):
setattr(inst, key, None)
-class ComplexModelMeta(with_metaclass(Prepareable, type(ModelBase))):
+class ComplexModelMeta(type(ModelBase), metaclass=Prepareable):
"""This metaclass sets ``_type_info``, ``__type_name__`` and ``__extends__``
which are going to be used for (de)serialization and schema generation.
"""
@@ -650,8 +677,9 @@ def __new__(cls, cls_name, cls_bases, cls_dict):
"""This function initializes the class and registers attributes."""
attrs = _gen_attrs(cls_bases, cls_dict)
- assert issubclass(attrs, ComplexModelBase.Attributes), \
- ("%r must be a ComplexModelBase.Attributes subclass" % attrs)
+ assert issubclass(attrs, ComplexModelBase.Attributes), (
+ "%r must be a ComplexModelBase.Attributes subclass" % attrs
+ )
cls_dict = _get_ordered_attributes(cls_name, cls_dict, attrs)
@@ -662,16 +690,15 @@ def __new__(cls, cls_name, cls_bases, cls_dict):
_type_info = _get_type_info(cls, cls_name, cls_bases, cls_dict, attrs)
# used for sub_name and sub_ns
- _type_info_alt = cls_dict['_type_info_alt'] = TypeInfo()
+ _type_info_alt = cls_dict["_type_info_alt"] = TypeInfo()
for b in cls_bases:
- if hasattr(b, '_type_info_alt'):
+ if hasattr(b, "_type_info_alt"):
_type_info_alt.update(b._type_info_alt)
_sanitize_type_info(cls_name, _type_info, _type_info_alt)
_sanitize_sqlalchemy_parameters(cls_dict, attrs)
- return super(ComplexModelMeta, cls).__new__(cls,
- cls_name, cls_bases, cls_dict)
+ return super(ComplexModelMeta, cls).__new__(cls, cls_name, cls_bases, cls_dict)
def __init__(self, cls_name, cls_bases, cls_dict):
type_info = self._type_info
@@ -700,10 +727,10 @@ def __init__(self, cls_name, cls_bases, cls_dict):
# replace SelfRerefence in arrays
elif issubclass(v, Array):
- v2, = v._type_info.values()
+ (v2,) = v._type_info.values()
while issubclass(v2, Array):
v = v2
- v2, = v2._type_info.values()
+ (v2,) = v2._type_info.values()
if issubclass(v2, SelfReference):
v._set_serializer(recust_selfref(v2, self))
@@ -732,8 +759,10 @@ def _get_prop(self):
def _set_prop(self, val):
if not (val is None or isinstance(val, v.Value)):
- raise ValueError("Invalid value %r, "
- "should be an instance of %r" % (val, v.Value))
+ raise ValueError(
+ "Invalid value %r, "
+ "should be an instance of %r" % (val, v.Value)
+ )
self.__dict__[k] = val
@@ -758,8 +787,11 @@ def _set_prop(self, val):
gen_spyne_info(self)
# For spyne objects being converted to a sqlalchemy table
- elif meta is not None and (tn is not None or t is not None) and \
- len(self._type_info) > 0:
+ elif (
+ meta is not None
+ and (tn is not None or t is not None)
+ and len(self._type_info) > 0
+ ):
from spyne.store.relational import gen_sqla_info
gen_sqla_info(self, cls_bases)
@@ -771,9 +803,6 @@ def _set_prop(self, val):
# declare them in the same order in the WSDL.
#
# For Python 3 __prepare__ works out of the box, see PEP 3115.
- # But we use `Preparable` metaclass for both Python 2 and Python 3 to
- # support six.add_metaclass decorator
- #
@classmethod
def __prepare__(mcs, name, bases, **kwds):
return odict()
@@ -887,25 +916,27 @@ def __init__(self, *args, **kwargs):
fti = cls.get_flat_type_info(cls)
if cls.__orig__ is not None:
- logger.warning("%r(0x%X) seems to be a customized class. It is not "
- "supposed to be instantiated. You have been warned.",
- cls, id(cls))
+ logger.warning(
+ "%r(0x%X) seems to be a customized class. It is not "
+ "supposed to be instantiated. You have been warned.",
+ cls,
+ id(cls),
+ )
logger.debug(traceback.format_stack())
if cls_attr._xml_tag_body_as is not None:
- for arg, (xtba_key, xtba_type) in \
- zip(args, cls_attr._xml_tag_body_as):
+ for arg, (xtba_key, xtba_type) in zip(args, cls_attr._xml_tag_body_as):
if xtba_key is not None and len(args) == 1:
attr = xtba_type.Attributes
_init_member(self, xtba_key, xtba_type, attr)
- self._safe_set(xtba_key, arg, xtba_type,
- xtba_type.Attributes)
+ self._safe_set(xtba_key, arg, xtba_type, xtba_type.Attributes)
elif len(args) > 0:
raise TypeError(
- "Positional argument is only for ComplexModels "
- "with XmlData field. You must use keyword "
- "arguments in any other case.")
+ "Positional argument is only for ComplexModels "
+ "with XmlData field. You must use keyword "
+ "arguments in any other case."
+ )
for k, v in fti.items():
attr = v.Attributes
@@ -930,10 +961,16 @@ def __getitem__(self, i):
return retval
def __repr__(self):
- return "%s(%s)" % (self.get_type_name(), ', '.join(
- ['%s=%r' % (k, self.__dict__.get(k))
+ return "%s(%s)" % (
+ self.get_type_name(),
+ ", ".join(
+ [
+ "%s=%r" % (k, self.__dict__.get(k))
for k in self.__class__.get_flat_type_info(self.__class__)
- if self.__dict__.get(k, None) is not None]))
+ if self.__dict__.get(k, None) is not None
+ ]
+ ),
+ )
def _safe_set(self, key, value, t, attrs):
if attrs.read_only:
@@ -943,15 +980,16 @@ def _safe_set(self, key, value, t, attrs):
setattr(self, key, value)
except AttributeError as e:
logger.exception(e)
- raise AttributeError("can't set %r attribute %s to %r" %
- (self.__class__, key, value))
+ raise AttributeError(
+ "can't set %r attribute %s to %r" % (self.__class__, key, value)
+ )
return True
@classmethod
def get_identifiers(cls):
for k, v in cls.get_flat_type_info(cls).items():
- if getattr(v.Attributes, 'primary_key', None):
+ if getattr(v.Attributes, "primary_key", None):
yield k, v
@classmethod
@@ -965,10 +1003,13 @@ def as_dict(self):
not nullable attributes.
"""
- return dict((
- (k, getattr(self, k)) for k in self.get_flat_type_info(self.__class__)
- if getattr(self, k) is not None
- ))
+ return dict(
+ (
+ (k, getattr(self, k))
+ for k in self.get_flat_type_info(self.__class__)
+ if getattr(self, k) is not None
+ )
+ )
@classmethod
def get_serialization_instance(cls, value):
@@ -993,8 +1034,9 @@ def get_serialization_instance(cls, value):
keys = cls.get_flat_type_info(cls).keys()
if not len(value) <= len(keys):
- logger.error("\n\tcls: %r" "\n\tvalue: %r" "\n\tkeys: %r",
- cls, value, keys)
+ logger.error(
+ "\n\tcls: %r" "\n\tvalue: %r" "\n\tkeys: %r", cls, value, keys
+ )
raise ValueError("Impossible sequence to instance conversion")
cls_orig = cls
@@ -1078,7 +1120,8 @@ def get_simple_type_info(cls, hier_delim="."):
names. Default is ``'.'``.
"""
return ComplexModelBase.get_simple_type_info_with_prot(
- cls, hier_delim=hier_delim)
+ cls, hier_delim=hier_delim
+ )
@staticmethod
@memoize
@@ -1094,13 +1137,15 @@ def get_simple_type_info_with_prot(cls, prot=None, hier_delim="."):
for k, v in fti.items():
sub_name = k
- queue.append((
- (k,),
- v,
- (sub_name,),
- (_is_array(v),),
- cls,
- ))
+ queue.append(
+ (
+ (k,),
+ v,
+ (sub_name,),
+ (_is_array(v),),
+ cls,
+ )
+ )
else:
for k, v in fti.items():
@@ -1109,13 +1154,15 @@ def get_simple_type_info_with_prot(cls, prot=None, hier_delim="."):
if sub_name is None:
sub_name = k
- queue.append((
- (k,),
- v,
- (sub_name,),
- (_is_array(v),),
- cls,
- ))
+ queue.append(
+ (
+ (k,),
+ v,
+ (sub_name,),
+ (_is_array(v),),
+ cls,
+ )
+ )
tags.add(cls)
@@ -1123,7 +1170,7 @@ def get_simple_type_info_with_prot(cls, prot=None, hier_delim="."):
keys, v, prefix, is_array, parent = queue.popleft()
k = keys[-1]
if issubclass(v, Array) and v.Attributes.max_occurs == 1:
- v, = v._type_info.values()
+ (v,) = v._type_info.values()
key = hier_delim.join(prefix)
if issubclass(v, ComplexModelBase):
@@ -1140,13 +1187,15 @@ def get_simple_type_info_with_prot(cls, prot=None, hier_delim="."):
if prot is None:
for k2, v2 in v.get_flat_type_info(v).items():
sub_name = k2
- queue.append((
- keys + (k2,),
- v2,
- prefix + (sub_name,),
- is_array + (_is_array(v),),
- v
- ))
+ queue.append(
+ (
+ keys + (k2,),
+ v2,
+ prefix + (sub_name,),
+ is_array + (_is_array(v),),
+ v,
+ )
+ )
else:
for k2, v2 in v.get_flat_type_info(v).items():
@@ -1155,20 +1204,21 @@ def get_simple_type_info_with_prot(cls, prot=None, hier_delim="."):
if sub_name is None:
sub_name = k2
- queue.append((
- keys + (k2,),
- v2,
- prefix + (sub_name,),
- is_array + (_is_array(v),),
- v,
- ))
+ queue.append(
+ (
+ keys + (k2,),
+ v2,
+ prefix + (sub_name,),
+ is_array + (_is_array(v),),
+ v,
+ )
+ )
else:
value = retval.get(key, None)
if value is not None:
- raise ValueError("%r.%s conflicts with %r" %
- (cls, k, value.path))
+ raise ValueError("%r.%s conflicts with %r" % (cls, k, value.path))
retval[key] = _SimpleTypeInfoElement(
path=keys,
@@ -1195,8 +1245,7 @@ def resolve_namespace(cls, default_ns, tags=None):
continue
if v.__type_name__ is ModelBase.Empty:
- v._fill_empty_type_name(cls.get_namespace(),
- cls.get_type_name(), k)
+ v._fill_empty_type_name(cls.get_namespace(), cls.get_type_name(), k)
v.resolve_namespace(v, default_ns, tags)
@@ -1214,11 +1263,17 @@ def resolve_namespace(cls, default_ns, tags=None):
def produce(namespace, type_name, members):
"""Lets you create a class programmatically."""
- return ComplexModelMeta(type_name, (ComplexModel,), odict({
- '__namespace__': namespace,
- '__type_name__': type_name,
- '_type_info': TypeInfo(members),
- }))
+ return ComplexModelMeta(
+ type_name,
+ (ComplexModel,),
+ odict(
+ {
+ "__namespace__": namespace,
+ "__type_name__": type_name,
+ "_type_info": TypeInfo(members),
+ }
+ ),
+ )
@classmethod
def customize(cls, **kwargs):
@@ -1230,14 +1285,14 @@ def customize(cls, **kwargs):
could cause memory leaks. You have been warned.
"""
- store_as = apply_pssm(kwargs.get('store_as', None))
+ store_as = apply_pssm(kwargs.get("store_as", None))
if store_as is not None:
- kwargs['store_as'] = store_as
+ kwargs["store_as"] = store_as
cls_name, cls_bases, cls_dict = cls._s_customize(**kwargs)
- cls_dict['__module__'] = cls.__module__
- if '__extends__' not in cls_dict:
- cls_dict['__extends__'] = cls.__extends__
+ cls_dict["__module__"] = cls.__module__
+ if "__extends__" not in cls_dict:
+ cls_dict["__extends__"] = cls.__extends__
retval = type(cls_name, cls_bases, cls_dict)
retval._type_info = TypeInfo(cls._type_info)
@@ -1274,7 +1329,7 @@ def customize(cls, **kwargs):
@classmethod
def _process_variants(cls, retval):
- orig = getattr(retval, '__orig__', None)
+ orig = getattr(retval, "__orig__", None)
if orig is not None:
if orig.Attributes._variants is None:
orig.Attributes._variants = WeakKeyDictionary()
@@ -1284,7 +1339,7 @@ def _process_variants(cls, retval):
@classmethod
def _append_field_impl(cls, field_name, field_type):
- assert isinstance(field_name, string_types)
+ assert isinstance(field_name, str)
dcaa = cls.Attributes._delayed_child_attrs_all
if dcaa is not None:
@@ -1321,7 +1376,7 @@ def _insert_to_variants(cls, index, field_name, field_type):
@classmethod
def _insert_field_impl(cls, index, field_name, field_type):
assert isinstance(index, int)
- assert isinstance(field_name, string_types)
+ assert isinstance(field_name, str)
dcaa = cls.Attributes._delayed_child_attrs_all
if dcaa is not None:
@@ -1351,7 +1406,7 @@ def _replace_in_variants(cls, field_name, field_type):
@classmethod
def _replace_field_impl(cls, field_name, field_type):
- assert isinstance(field_name, string_types)
+ assert isinstance(field_name, str)
cls._type_info[field_name] = field_type
@@ -1390,8 +1445,7 @@ def init_from(cls, other, **kwargs):
@classmethod
def __respawn__(cls, ctx=None, filters=None):
- if ctx is not None and ctx.in_object is not None and \
- len(ctx.in_object) > 0:
+ if ctx is not None and ctx.in_object is not None and len(ctx.in_object) > 0:
retval = next(iter(ctx.in_object))
if retval is not None:
return retval
@@ -1400,8 +1454,7 @@ def __respawn__(cls, ctx=None, filters=None):
return cls.get_deserialization_instance(ctx)
-@add_metaclass(ComplexModelMeta)
-class ComplexModel(ComplexModelBase):
+class ComplexModel(ComplexModelBase, metaclass=ComplexModelMeta):
"""The general complexType factory. The __call__ method of this class will
return instances, contrary to primivites where the same call will result in
customized duplicates of the original class definition.
@@ -1410,8 +1463,7 @@ class ComplexModel(ComplexModelBase):
"""
-@add_metaclass(ComplexModelMeta)
-class Array(ComplexModelBase):
+class Array(ComplexModelBase, metaclass=ComplexModelMeta):
"""This class generates a ComplexModel child that has one attribute that has
the same name as the serialized class. It's contained in a Python list.
"""
@@ -1422,20 +1474,20 @@ class Attributes(ComplexModelBase.Attributes):
def __new__(cls, serializer, member_name=None, wrapped=True, **kwargs):
if not wrapped:
if serializer.Attributes.max_occurs == 1:
- kwargs['max_occurs'] = 'unbounded'
+ kwargs["max_occurs"] = "unbounded"
return serializer.customize(**kwargs)
retval = cls.customize(**kwargs)
- _serializer = _get_spyne_type(cls.__name__, '__serializer__', serializer)
+ _serializer = _get_spyne_type(cls.__name__, "__serializer__", serializer)
if _serializer is None:
raise ValueError("serializer=%r is not a valid spyne type" % serializer)
if issubclass(_serializer, SelfReference):
- # hack to make sure the array passes ComplexModel sanity checks
- # that are there to prevent empty arrays.
- retval._type_info = {'_bogus': _serializer}
+ # hack to make sure the array passes ComplexModel sanity checks
+ # that are there to prevent empty arrays.
+ retval._type_info = {"_bogus": _serializer}
else:
retval._set_serializer(_serializer, member_name)
@@ -1450,30 +1502,28 @@ def _fill_empty_type_name(cls, parent_ns, parent_tn, k):
cls.__namespace__ = parent_ns
tn = "%s_%s%s" % (parent_tn, k, const.TYPE_SUFFIX)
- child_v, = cls._type_info.values()
+ (child_v,) = cls._type_info.values()
child_v.__type_name__ = tn
cls._type_info = TypeInfo({tn: child_v})
- cls.__type_name__ = '%s%s%s' % (const.ARRAY_PREFIX, tn,
- const.ARRAY_SUFFIX)
+ cls.__type_name__ = "%s%s%s" % (const.ARRAY_PREFIX, tn, const.ARRAY_SUFFIX)
extends = child_v.__extends__
while extends is not None and extends.get_type_name() is cls.Empty:
- extends._fill_empty_type_name(parent_ns, parent_tn,
- k + const.PARENT_SUFFIX)
+ extends._fill_empty_type_name(parent_ns, parent_tn, k + const.PARENT_SUFFIX)
extends = extends.__extends__
@classmethod
def customize(cls, **kwargs):
- serializer_attrs = kwargs.get('serializer_attrs', None)
+ serializer_attrs = kwargs.get("serializer_attrs", None)
if serializer_attrs is None:
return super(Array, cls).customize(**kwargs)
- del kwargs['serializer_attrs']
+ del kwargs["serializer_attrs"]
- logger.debug('Pass serializer attrs %r', serializer_attrs)
+ logger.debug("Pass serializer attrs %r", serializer_attrs)
- serializer, = cls._type_info.values()
+ (serializer,) = cls._type_info.values()
return cls(serializer.customize(**serializer_attrs)).customize(**kwargs)
@classmethod
@@ -1487,16 +1537,18 @@ def _set_serializer(cls, serializer, member_name=None):
if member_name is None:
member_name = serializer.get_type_name()
- cls.__type_name__ = '%s%s%s' % (const.ARRAY_PREFIX,
- serializer.get_type_name(),
- const.ARRAY_SUFFIX)
+ cls.__type_name__ = "%s%s%s" % (
+ const.ARRAY_PREFIX,
+ serializer.get_type_name(),
+ const.ARRAY_SUFFIX,
+ )
# hack to default to unbounded arrays when the user didn't specify
# max_occurs.
if serializer.Attributes.max_occurs == 1:
- serializer = serializer.customize(max_occurs=decimal.Decimal('inf'))
+ serializer = serializer.customize(max_occurs=decimal.Decimal("inf"))
- assert isinstance(member_name, string_types), member_name
+ assert isinstance(member_name, str), member_name
cls._type_info = TypeInfo({member_name: serializer})
# the array belongs to its child's namespace, it doesn't have its own
@@ -1560,6 +1612,7 @@ class Push(PushBase):
stuff as `deferToThread` is not guaranteed to restore original thread
context.
"""
+
pass
@@ -1605,8 +1658,7 @@ def TTableModel(metadata=None, base=None, metaclass=None):
if metaclass is None:
metaclass = ComplexModelMeta
- @add_metaclass(metaclass)
- class TableModel(base):
+ class TableModel(base, metaclass=metaclass):
class Attributes(ComplexModelBase.Attributes):
sqla_metadata = metadata if metadata is not None else MetaData()
@@ -1621,14 +1673,17 @@ def Mandatory(cls, **_kwargs):
kwargs = dict(min_occurs=1, nillable=False)
if cls.get_type_name() is not cls.Empty:
- kwargs['type_name'] = '%s%s%s' % (const.MANDATORY_PREFIX,
- cls.get_type_name(), const.MANDATORY_SUFFIX)
+ kwargs["type_name"] = "%s%s%s" % (
+ const.MANDATORY_PREFIX,
+ cls.get_type_name(),
+ const.MANDATORY_SUFFIX,
+ )
kwargs.update(_kwargs)
if issubclass(cls, Unicode):
kwargs.update(dict(min_len=1))
elif issubclass(cls, Array):
- (k,v), = cls._type_info.items()
+ ((k, v),) = cls._type_info.items()
if v.Attributes.min_occurs == 0:
cls._type_info[k] = Mandatory(v)
diff --git a/spyne/model/enum.py b/spyne/model/enum.py
index ec0901d21..1dbc31185 100644
--- a/spyne/model/enum.py
+++ b/spyne/model/enum.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -21,6 +20,7 @@
# adapted from: http://code.activestate.com/recipes/413486/
+
class EnumBase(SimpleModel):
__namespace__ = None
@@ -32,9 +32,8 @@ def resolve_namespace(cls, default_ns, tags=None):
@staticmethod
def validate_string(cls, value):
- return ( SimpleModel.validate_string(cls, value)
- and value in cls.__values__
- )
+ return SimpleModel.validate_string(cls, value) and value in cls.__values__
+
def Enum(*values, **kwargs):
"""The enum type that can only return ``True`` when compared to types of
@@ -59,17 +58,17 @@ def Enum(*values, **kwargs):
In the above example, ``SomeEnum`` can be used as a regular Spyne model.
"""
- type_name = kwargs.get('type_name', None)
- docstr = kwargs.get('doc', '')
+ type_name = kwargs.get("type_name", None)
+ docstr = kwargs.get("doc", "")
if type_name is None:
raise Exception("Please specify 'type_name' as a keyword argument")
assert len(values) > 0, "Empty enums are meaningless"
- maximum = len(values) # to make __invert__ work
+ maximum = len(values) # to make __invert__ work
class EnumValue(object):
- __slots__ = ('__value',)
+ __slots__ = ("__value",)
def __init__(self, value):
self.__value = value
@@ -110,10 +109,10 @@ def __getitem__(self, i):
return values[i]
def __repr__(self):
- return 'Enum' + str(enumerate(values))
+ return "Enum" + str(enumerate(values))
def __str__(self):
- return 'enum ' + str(values)
+ return "enum " + str(values)
for i, v in enumerate(values):
setattr(EnumType, v, EnumValue(i))
diff --git a/spyne/model/fault.py b/spyne/model/fault.py
index 89c9f2983..ca998315a 100644
--- a/spyne/model/fault.py
+++ b/spyne/model/fault.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -17,35 +16,32 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
-from warnings import warn
from collections import defaultdict
+from warnings import warn
import spyne.const
-
+from spyne.model.complex import ComplexModelBase, ComplexModelMeta
from spyne.model.primitive import Any
-from spyne.util.six import add_metaclass
-
-from spyne.model.complex import ComplexModelMeta
-from spyne.model.complex import ComplexModelBase
-
class FaultMeta(ComplexModelMeta):
def __init__(self, cls_name, cls_bases, cls_dict):
super(FaultMeta, self).__init__(cls_name, cls_bases, cls_dict)
- code = cls_dict.get('CODE', None)
+ code = cls_dict.get("CODE", None)
if code is not None:
target = Fault.REGISTERED[code]
target.add(self)
if spyne.const.WARN_ON_DUPLICATE_FAULTCODE and len(target) > 1:
- warn("Duplicate faultcode {} detected for classes {}"
- .format(code, target))
+ warn(
+ "Duplicate faultcode {} detected for classes {}".format(
+ code, target
+ )
+ )
-@add_metaclass(FaultMeta)
-class Fault(ComplexModelBase, Exception):
+class Fault(ComplexModelBase, Exception, metaclass=FaultMeta):
"""Use this class as a base for all public exceptions.
The Fault object adheres to the
`SOAP 1.1 Fault definition `_,
@@ -80,8 +76,14 @@ class Fault(ComplexModelBase, Exception):
CODE = None
- def __init__(self, faultcode='Server', faultstring="", faultactor="",
- detail=None, lang=spyne.DEFAULT_LANGUAGE):
+ def __init__(
+ self,
+ faultcode="Server",
+ faultstring="",
+ faultactor="",
+ detail=None,
+ lang=spyne.DEFAULT_LANGUAGE,
+ ):
self.faultcode = faultcode
self.faultstring = faultstring or self.get_type_name()
self.faultactor = faultactor
@@ -96,11 +98,18 @@ def __str__(self):
def __repr__(self):
if self.detail is None:
- return "%s(%s: %r)" % (self.__class__.__name__,
- self.faultcode, self.faultstring)
-
- return "%s(%s: %r detail: %r)" % (self.__class__.__name__,
- self.faultcode, self.faultstring, self.detail)
+ return "%s(%s: %r)" % (
+ self.__class__.__name__,
+ self.faultcode,
+ self.faultstring,
+ )
+
+ return "%s(%s: %r detail: %r)" % (
+ self.__class__.__name__,
+ self.faultcode,
+ self.faultstring,
+ self.detail,
+ )
@staticmethod
def to_dict(cls, value, prot):
@@ -111,7 +120,7 @@ def to_dict(cls, value, prot):
"detail": str(value),
}
- retval = {
+ retval = {
"faultcode": value.faultcode,
"faultstring": value.faultstring,
}
@@ -138,9 +147,9 @@ def to_list(cls, value, prot=None):
if not issubclass(cls, Fault):
return [
"Server.Unknown", # faultcode
- cls.__name__, # faultstring
- "", # faultactor
- str(value), # detail
+ cls.__name__, # faultstring
+ "", # faultactor
+ str(value), # detail
]
retval = [
@@ -163,9 +172,9 @@ def to_list(cls, value, prot=None):
@classmethod
def to_bytes_iterable(cls, value):
return [
- value.faultcode.encode('utf8'),
- b'\n\n',
- value.faultstring.encode('utf8'),
+ value.faultcode.encode("utf8"),
+ b"\n\n",
+ value.faultstring.encode("utf8"),
]
def detail_to_doc(self, prot):
@@ -173,3 +182,17 @@ def detail_to_doc(self, prot):
def detail_from_doc(self, prot, doc):
self.detail = doc
+
+
+class ValidationError(Fault):
+ """Raised when the input stream does not adhere to type constraints."""
+
+ CODE = "Client.ValidationError"
+
+ def __init__(self, obj, custom_msg="The value %r could not be validated."):
+ try:
+ msg = custom_msg % (obj,)
+ except TypeError:
+ msg = custom_msg
+
+ super(ValidationError, self).__init__(self.CODE, msg)
diff --git a/spyne/model/primitive/__init__.py b/spyne/model/primitive/__init__.py
index 64f1ba467..c51e5098d 100644
--- a/spyne/model/primitive/__init__.py
+++ b/spyne/model/primitive/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,93 +17,96 @@
#
NATIVE_MAP = {}
-string_encoding = 'UTF-8' # ???
-
-from spyne.model.primitive._base import Any
-from spyne.model.primitive._base import AnyDict
-from spyne.model.primitive._base import AnyHtml
-from spyne.model.primitive._base import AnyXml
-from spyne.model.primitive._base import Boolean
-
-from spyne.model.primitive.string import Unicode
-from spyne.model.primitive.string import String
-from spyne.model.primitive.string import AnyUri
-from spyne.model.primitive.string import Uuid
-from spyne.model.primitive.string import ImageUri
-from spyne.model.primitive.string import Ltree
-from spyne.model.primitive.string import MimeType
-from spyne.model.primitive.string import MimeTypeStrict
-from spyne.model.primitive.string import MediaType
-from spyne.model.primitive.string import MediaTypeStrict
-
-from spyne.model.primitive.xml import ID
-from spyne.model.primitive.xml import Token
-from spyne.model.primitive.xml import NMToken
-from spyne.model.primitive.xml import Name
-from spyne.model.primitive.xml import NCName
-from spyne.model.primitive.xml import QName
-from spyne.model.primitive.xml import Language
-from spyne.model.primitive.xml import NormalizedString
-
-from spyne.model.primitive.spatial import Point
-from spyne.model.primitive.spatial import Line
-from spyne.model.primitive.spatial import LineString
-from spyne.model.primitive.spatial import Polygon
-from spyne.model.primitive.spatial import MultiPoint
-from spyne.model.primitive.spatial import MultiLine
-from spyne.model.primitive.spatial import MultiLineString
-from spyne.model.primitive.spatial import MultiPolygon
+string_encoding = "UTF-8" # ???
+
+from spyne.model.primitive._base import Any, AnyDict, AnyHtml, AnyXml, Boolean
# Date/Time types
-from spyne.model.primitive.datetime import Date
-from spyne.model.primitive.datetime import DateTime
-from spyne.model.primitive.datetime import Duration
-from spyne.model.primitive.datetime import Time
+from spyne.model.primitive.datetime import Date, DateTime, Duration, Time
+from spyne.model.primitive.network import (
+ IpAddress,
+ Ipv4Address,
+ Ipv6Address,
+ MacAddress,
+)
# Numbers
-from spyne.model.primitive.number import Decimal
-from spyne.model.primitive.number import Double
-from spyne.model.primitive.number import Float
-
-from spyne.model.primitive.number import Integer8
-from spyne.model.primitive.number import Byte
-from spyne.model.primitive.number import Integer16
-from spyne.model.primitive.number import Short
-from spyne.model.primitive.number import Integer32
-from spyne.model.primitive.number import Int
-from spyne.model.primitive.number import Integer64
-from spyne.model.primitive.number import Long
-from spyne.model.primitive.number import Integer
-from spyne.model.primitive.number import NumberLimitsWarning
-
-from spyne.model.primitive.number import UnsignedInteger8
-from spyne.model.primitive.number import UnsignedByte
-from spyne.model.primitive.number import UnsignedInteger16
-from spyne.model.primitive.number import UnsignedShort
-from spyne.model.primitive.number import UnsignedInteger32
-from spyne.model.primitive.number import UnsignedInt
-from spyne.model.primitive.number import UnsignedInteger64
-from spyne.model.primitive.number import UnsignedLong
-from spyne.model.primitive.number import NonNegativeInteger # Xml Schema calls it so
-from spyne.model.primitive.number import UnsignedInteger
-
-from spyne.model.primitive.network import MacAddress
-from spyne.model.primitive.network import IpAddress
-from spyne.model.primitive.network import Ipv4Address
-from spyne.model.primitive.network import Ipv6Address
+from spyne.model.primitive.number import NonNegativeInteger # Xml Schema calls it so
+from spyne.model.primitive.number import (
+ Byte,
+ Decimal,
+ Double,
+ Float,
+ Int,
+ Integer,
+ Integer8,
+ Integer16,
+ Integer32,
+ Integer64,
+ Long,
+ NumberLimitsWarning,
+ Short,
+ UnsignedByte,
+ UnsignedInt,
+ UnsignedInteger,
+ UnsignedInteger8,
+ UnsignedInteger16,
+ UnsignedInteger32,
+ UnsignedInteger64,
+ UnsignedLong,
+ UnsignedShort,
+)
+from spyne.model.primitive.spatial import (
+ Line,
+ LineString,
+ MultiLine,
+ MultiLineString,
+ MultiPoint,
+ MultiPolygon,
+ Point,
+ Polygon,
+)
+from spyne.model.primitive.string import (
+ AnyUri,
+ ImageUri,
+ Ltree,
+ MediaType,
+ MediaTypeStrict,
+ MimeType,
+ MimeTypeStrict,
+ String,
+ Unicode,
+ Uuid,
+)
+from spyne.model.primitive.xml import (
+ ID,
+ Language,
+ Name,
+ NCName,
+ NMToken,
+ NormalizedString,
+ QName,
+ Token,
+)
# This class is DEPRECATED. Use the spyne.model.Mandatory like this:
# >>> from spyne.model import Mandatory as M, Unicode
# >>> MandatoryEmail = M(Unicode(pattern='[^@]+@[^@]+'))
class Mandatory:
- Unicode = Unicode(type_name="MandatoryString", min_occurs=1, nillable=False, min_len=1)
- String = String(type_name="MandatoryString", min_occurs=1, nillable=False, min_len=1)
+ Unicode = Unicode(
+ type_name="MandatoryString", min_occurs=1, nillable=False, min_len=1
+ )
+ String = String(
+ type_name="MandatoryString", min_occurs=1, nillable=False, min_len=1
+ )
AnyXml = AnyXml(type_name="MandatoryXml", min_occurs=1, nillable=False)
AnyDict = AnyDict(type_name="MandatoryDict", min_occurs=1, nillable=False)
AnyUri = AnyUri(type_name="MandatoryUri", min_occurs=1, nillable=False, min_len=1)
- ImageUri = ImageUri(type_name="MandatoryImageUri", min_occurs=1, nillable=False, min_len=1)
+ ImageUri = ImageUri(
+ type_name="MandatoryImageUri", min_occurs=1, nillable=False, min_len=1
+ )
Boolean = Boolean(type_name="MandatoryBoolean", min_occurs=1, nillable=False)
@@ -128,11 +130,21 @@ class Mandatory:
Short = Integer16
Byte = Integer8
- UnsignedInteger = UnsignedInteger(type_name="MandatoryUnsignedInteger", min_occurs=1, nillable=False)
- UnsignedInteger64 = UnsignedInteger64(type_name="MandatoryUnsignedLong", min_occurs=1, nillable=False)
- UnsignedInteger32 = UnsignedInteger32(type_name="MandatoryUnsignedInt", min_occurs=1, nillable=False)
- UnsignedInteger16 = UnsignedInteger16(type_name="MandatoryUnsignedShort", min_occurs=1, nillable=False)
- UnsignedInteger8 = UnsignedInteger8(type_name="MandatoryUnsignedByte", min_occurs=1, nillable=False)
+ UnsignedInteger = UnsignedInteger(
+ type_name="MandatoryUnsignedInteger", min_occurs=1, nillable=False
+ )
+ UnsignedInteger64 = UnsignedInteger64(
+ type_name="MandatoryUnsignedLong", min_occurs=1, nillable=False
+ )
+ UnsignedInteger32 = UnsignedInteger32(
+ type_name="MandatoryUnsignedInt", min_occurs=1, nillable=False
+ )
+ UnsignedInteger16 = UnsignedInteger16(
+ type_name="MandatoryUnsignedShort", min_occurs=1, nillable=False
+ )
+ UnsignedInteger8 = UnsignedInteger8(
+ type_name="MandatoryUnsignedByte", min_occurs=1, nillable=False
+ )
UnsignedLong = UnsignedInteger64
UnsignedInt = UnsignedInteger32
@@ -146,10 +158,16 @@ class Mandatory:
LineString = Line
Polygon = Polygon(type_name="Polygon", min_len=1, min_occurs=1, nillable=False)
- MultiPoint = MultiPoint(type_name="MandatoryMultiPoint", min_len=1, min_occurs=1, nillable=False)
- MultiLine = MultiLine(type_name="MandatoryMultiLineString", min_len=1, min_occurs=1, nillable=False)
+ MultiPoint = MultiPoint(
+ type_name="MandatoryMultiPoint", min_len=1, min_occurs=1, nillable=False
+ )
+ MultiLine = MultiLine(
+ type_name="MandatoryMultiLineString", min_len=1, min_occurs=1, nillable=False
+ )
MultiLineString = MultiLine
- MultiPolygon = MultiPolygon(type_name="MandatoryMultiPolygon", min_len=1, min_occurs=1, nillable=False)
+ MultiPolygon = MultiPolygon(
+ type_name="MandatoryMultiPolygon", min_len=1, min_occurs=1, nillable=False
+ )
assert Mandatory.Long == Mandatory.Integer64
diff --git a/spyne/model/primitive/_base.py b/spyne/model/primitive/_base.py
index d6ea85fdc..75e7db6d3 100644
--- a/spyne/model/primitive/_base.py
+++ b/spyne/model/primitive/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -25,12 +24,11 @@
See :mod:`spyne.protocol._model` for {to,from}_string implementations.
"""
-
from __future__ import absolute_import
from spyne.model import SimpleModel
+from spyne.model._base import apply_pssm, json, msgpack, xml
from spyne.model.primitive import NATIVE_MAP
-from spyne.model._base import apply_pssm, msgpack, xml, json
def re_match_with_span(attr, value):
@@ -49,7 +47,7 @@ class AnyXml(SimpleModel):
"""An xml node that can contain any number of sub nodes. It's represented by
an ElementTree object."""
- __type_name__ = 'anyType'
+ __type_name__ = "anyType"
class Attributes(SimpleModel.Attributes):
namespace = None
@@ -65,24 +63,24 @@ def customize(cls, **kwargs):
"""Duplicates cls and overwrites the values in ``cls.Attributes`` with
``**kwargs`` and returns the new class."""
- store_as = apply_pssm(kwargs.get('store_as', None))
+ store_as = apply_pssm(kwargs.get("store_as", None))
if store_as is not None:
- kwargs['store_as'] = store_as
+ kwargs["store_as"] = store_as
return super(Any, cls).customize(**kwargs)
class AnyHtml(SimpleModel):
- __type_name__ = 'string'
+ __type_name__ = "string"
@classmethod
def customize(cls, **kwargs):
"""Duplicates cls and overwrites the values in ``cls.Attributes`` with
``**kwargs`` and returns the new class."""
- store_as = apply_pssm(kwargs.get('store_as', None))
+ store_as = apply_pssm(kwargs.get("store_as", None))
if store_as is not None:
- kwargs['store_as'] = store_as
+ kwargs["store_as"] = store_as
return super(AnyHtml, cls).customize(**kwargs)
@@ -92,7 +90,7 @@ class AnyDict(SimpleModel):
types. Its serialization is protocol-dependent.
"""
- __type_name__ = 'anyType'
+ __type_name__ = "anyType"
Value = dict
class Attributes(SimpleModel.Attributes):
@@ -106,9 +104,9 @@ def customize(cls, **kwargs):
"""Duplicates cls and overwrites the values in ``cls.Attributes`` with
``**kwargs`` and returns the new class."""
- store_as = apply_pssm(kwargs.get('store_as', None))
+ store_as = apply_pssm(kwargs.get("store_as", None))
if store_as is not None:
- kwargs['store_as'] = store_as
+ kwargs["store_as"] = store_as
return super(AnyDict, cls).customize(**kwargs)
@@ -122,9 +120,11 @@ class Attributes(SimpleModel.Attributes):
builtins. It makes sense to specify this only when this object belongs
to a `ComplexModel` sublass."""
- __type_name__ = 'boolean'
+ __type_name__ = "boolean"
-NATIVE_MAP.update({
- bool: Boolean,
-})
+NATIVE_MAP.update(
+ {
+ bool: Boolean,
+ }
+)
diff --git a/spyne/model/primitive/datetime.py b/spyne/model/primitive/datetime.py
index 161b85ee4..7abc8a9bf 100644
--- a/spyne/model/primitive/datetime.py
+++ b/spyne/model/primitive/datetime.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -19,18 +18,18 @@
from __future__ import absolute_import
-import re
-import spyne
import datetime
+import re
+import spyne
from spyne.model import SimpleModel
from spyne.model.primitive import NATIVE_MAP
-FLOAT_PATTERN = r'-?[0-9]+\.?[0-9]*(e-?[0-9]+)?'
-DATE_PATTERN = r'(?P\d{4})-(?P\d{2})-(?P\d{2})'
-TIME_PATTERN = r'(?P
\d{2}):(?P\d{2}):(?P\d{2})(?P\.\d+)?'
-OFFSET_PATTERN = r'(?P[+-]\d{2}):(?P\d{2})'
-DATETIME_PATTERN = DATE_PATTERN + '[T ]' + TIME_PATTERN
+FLOAT_PATTERN = r"-?[0-9]+\.?[0-9]*(e-?[0-9]+)?"
+DATE_PATTERN = r"(?P\d{4})-(?P\d{2})-(?P\d{2})"
+TIME_PATTERN = r"(?P
\d{2}):(?P\d{2}):(?P\d{2})(?P\.\d+)?"
+OFFSET_PATTERN = r"(?P[+-]\d{2}):(?P\d{2})"
+DATETIME_PATTERN = DATE_PATTERN + "[T ]" + TIME_PATTERN
class Time(SimpleModel):
@@ -39,7 +38,7 @@ class Time(SimpleModel):
Native type is :class:`datetime.time`.
"""
- __type_name__ = 'time'
+ __type_name__ = "time"
Value = datetime.time
class Attributes(SimpleModel.Attributes):
@@ -70,23 +69,27 @@ class Attributes(SimpleModel.Attributes):
@staticmethod
def is_default(cls):
- return ( SimpleModel.is_default(cls)
- and cls.Attributes.gt == Time.Attributes.gt
- and cls.Attributes.ge == Time.Attributes.ge
- and cls.Attributes.lt == Time.Attributes.lt
- and cls.Attributes.le == Time.Attributes.le
- and cls.Attributes.pattern == Time.Attributes.pattern
+ return (
+ SimpleModel.is_default(cls)
+ and cls.Attributes.gt == Time.Attributes.gt
+ and cls.Attributes.ge == Time.Attributes.ge
+ and cls.Attributes.lt == Time.Attributes.lt
+ and cls.Attributes.le == Time.Attributes.le
+ and cls.Attributes.pattern == Time.Attributes.pattern
)
@staticmethod
def validate_native(cls, value):
return SimpleModel.validate_native(cls, value) and (
- value is None or (
- (cls.Attributes.gt is None or value > cls.Attributes.gt)
+ value is None
+ or (
+ (cls.Attributes.gt is None or value > cls.Attributes.gt)
and value >= cls.Attributes.ge
- and (cls.Attributes.lt is None or value < cls.Attributes.lt)
+ and (cls.Attributes.lt is None or value < cls.Attributes.lt)
and value <= cls.Attributes.le
- ))
+ )
+ )
+
_min_dt = datetime.datetime.min.replace(tzinfo=spyne.LOCAL_TZ)
_max_dt = datetime.datetime.max.replace(tzinfo=spyne.LOCAL_TZ)
@@ -102,11 +105,11 @@ class DateTime(SimpleModel):
Native type is :class:`datetime.datetime`.
"""
- __type_name__ = 'dateTime'
+ __type_name__ = "dateTime"
Value = datetime.datetime
_local_re = re.compile(DATETIME_PATTERN)
- _utc_re = re.compile(DATETIME_PATTERN + 'Z')
+ _utc_re = re.compile(DATETIME_PATTERN + "Z")
_offset_re = re.compile(DATETIME_PATTERN + OFFSET_PATTERN)
class Attributes(SimpleModel.Attributes):
@@ -185,12 +188,13 @@ class Attributes(SimpleModel.Attributes):
@staticmethod
def is_default(cls):
- return ( SimpleModel.is_default(cls)
- and cls.Attributes.gt == DateTime.Attributes.gt
- and cls.Attributes.ge == DateTime.Attributes.ge
- and cls.Attributes.lt == DateTime.Attributes.lt
- and cls.Attributes.le == DateTime.Attributes.le
- and cls.Attributes.pattern == DateTime.Attributes.pattern
+ return (
+ SimpleModel.is_default(cls)
+ and cls.Attributes.gt == DateTime.Attributes.gt
+ and cls.Attributes.ge == DateTime.Attributes.ge
+ and cls.Attributes.lt == DateTime.Attributes.lt
+ and cls.Attributes.le == DateTime.Attributes.le
+ and cls.Attributes.pattern == DateTime.Attributes.pattern
)
@staticmethod
@@ -198,14 +202,16 @@ def validate_native(cls, value):
if isinstance(value, datetime.datetime) and value.tzinfo is None:
value = value.replace(tzinfo=spyne.LOCAL_TZ)
return SimpleModel.validate_native(cls, value) and (
- value is None or (
+ value is None
+ or (
# min_dt is also a valid value if gt is intact.
- (cls.Attributes.gt is None or value > cls.Attributes.gt)
+ (cls.Attributes.gt is None or value > cls.Attributes.gt)
and value >= cls.Attributes.ge
# max_dt is also a valid value if lt is intact.
and (cls.Attributes.lt is None or value < cls.Attributes.lt)
and value <= cls.Attributes.le
- ))
+ )
+ )
class Date(DateTime):
@@ -214,9 +220,9 @@ class Date(DateTime):
Native type is :class:`datetime.date`.
"""
- __type_name__ = 'date'
+ __type_name__ = "date"
- _offset_re = re.compile(DATE_PATTERN + '(' + OFFSET_PATTERN + '|Z)')
+ _offset_re = re.compile(DATE_PATTERN + "(" + OFFSET_PATTERN + "|Z)")
Value = datetime.date
class Attributes(DateTime.Attributes):
@@ -245,15 +251,15 @@ class Attributes(DateTime.Attributes):
"""A regular expression that matches the whole date. See here for more
info: http://www.regular-expressions.info/xml.html"""
-
@staticmethod
def is_default(cls):
- return ( SimpleModel.is_default(cls)
- and cls.Attributes.gt == Date.Attributes.gt
- and cls.Attributes.ge == Date.Attributes.ge
- and cls.Attributes.lt == Date.Attributes.lt
- and cls.Attributes.le == Date.Attributes.le
- and cls.Attributes.pattern == Date.Attributes.pattern
+ return (
+ SimpleModel.is_default(cls)
+ and cls.Attributes.gt == Date.Attributes.gt
+ and cls.Attributes.ge == Date.Attributes.ge
+ and cls.Attributes.lt == Date.Attributes.lt
+ and cls.Attributes.le == Date.Attributes.le
+ and cls.Attributes.pattern == Date.Attributes.pattern
)
@@ -261,13 +267,15 @@ def is_default(cls):
class Duration(SimpleModel):
"""Native type is :class:`datetime.timedelta`."""
- __type_name__ = 'duration'
+ __type_name__ = "duration"
Value = datetime.timedelta
-NATIVE_MAP.update({
- datetime.datetime: DateTime,
- datetime.time: Time,
- datetime.date: Date,
- datetime.timedelta: Duration,
-})
+NATIVE_MAP.update(
+ {
+ datetime.datetime: DateTime,
+ datetime.time: Time,
+ datetime.date: Date,
+ datetime.timedelta: Duration,
+ }
+)
diff --git a/spyne/model/primitive/network.py b/spyne/model/primitive/network.py
index dfbc292ed..9627959e4 100644
--- a/spyne/model/primitive/network.py
+++ b/spyne/model/primitive/network.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -21,16 +20,18 @@
from spyne.model.primitive._base import re_match_with_span
from spyne.model.primitive.string import Unicode
-
_PATT_MAC = "([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})"
def _validate_string(cls, value):
- return ( SimpleModel.validate_string(cls, value)
- and (value is None or (
+ return SimpleModel.validate_string(cls, value) and (
+ value is None
+ or (
cls.Attributes.min_len <= len(value) <= cls.Attributes.max_len
and re_match_with_span(cls.Attributes, value)
- )))
+ )
+ )
+
_mac_validate = {
None: _validate_string,
@@ -39,11 +40,13 @@ def _validate_string(cls, value):
_MacBase = Unicode(max_len=17, min_len=17, pattern=_PATT_MAC)
+
+
class MacAddress(_MacBase):
"""Unicode subclass for a MAC address."""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'addr_mac'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "addr_mac"
class Attributes(_MacBase.Attributes):
serialize_as = None
@@ -58,7 +61,7 @@ def validate_native(cls, value):
_PATT_IPV4_FRAG = r"(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])"
-_PATT_IPV4 = r"(%(P4)s\.){3,3}%(P4)s" % {'P4': _PATT_IPV4_FRAG}
+_PATT_IPV4 = r"(%(P4)s\.){3,3}%(P4)s" % {"P4": _PATT_IPV4_FRAG}
_ipv4_validate = {
@@ -68,11 +71,13 @@ def validate_native(cls, value):
_Ipv4Base = Unicode(15, pattern=_PATT_IPV4)
+
+
class Ipv4Address(_Ipv4Base):
"""Unicode subclass for an IPv4 address."""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'addr_ipv4'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "addr_ipv4"
class Attributes(_Ipv4Base.Attributes):
serialize_as = None
@@ -88,20 +93,22 @@ def validate_native(cls, value):
# http://stackoverflow.com/a/1934546
_PATT_IPV6_FRAG = "[0-9a-fA-F]{1,4}"
-_PATT_IPV6 = ("("
- "(%(P6)s:){7,7}%(P6)s|" # 1:2:3:4:5:6:7:8
- "(%(P6)s:){1,7}:|" # 1:: 1:2:3:4:5:6:7::
- "(%(P6)s:){1,6}:%(P6)s|" # 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
- "(%(P6)s:){1,5}(:%(P6)s){1,2}|" # 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
- "(%(P6)s:){1,4}(:%(P6)s){1,3}|" # 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
- "(%(P6)s:){1,3}(:%(P6)s){1,4}|" # 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
- "(%(P6)s:){1,2}(:%(P6)s){1,5}|" # 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
- "%(P6)s:((:%(P6)s){1,6})|" # 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
- ":((:%(P6)s){1,7}|:)|" # ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
- "fe80:(:%(P6)s){0,4}%%[0-9a-zA-Z]{1,}|" # fe80::7:8%eth0 fe80::7:8%1 (link-local IPv6 addresses with zone index)
+_PATT_IPV6 = (
+ "("
+ "(%(P6)s:){7,7}%(P6)s|" # 1:2:3:4:5:6:7:8
+ "(%(P6)s:){1,7}:|" # 1:: 1:2:3:4:5:6:7::
+ "(%(P6)s:){1,6}:%(P6)s|" # 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
+ "(%(P6)s:){1,5}(:%(P6)s){1,2}|" # 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
+ "(%(P6)s:){1,4}(:%(P6)s){1,3}|" # 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
+ "(%(P6)s:){1,3}(:%(P6)s){1,4}|" # 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
+ "(%(P6)s:){1,2}(:%(P6)s){1,5}|" # 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
+ "%(P6)s:((:%(P6)s){1,6})|" # 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
+ ":((:%(P6)s){1,7}|:)|" # ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
+ "fe80:(:%(P6)s){0,4}%%[0-9a-zA-Z]{1,}|" # fe80::7:8%eth0 fe80::7:8%1 (link-local IPv6 addresses with zone index)
"::(ffff(:0{1,4}){0,1}:){0,1}%(A4)s|" # ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
- "(%(P6)s:){1,4}:%(A4)s" # 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
-")") % {'P6': _PATT_IPV6_FRAG, 'A4': _PATT_IPV4}
+ "(%(P6)s:){1,4}:%(A4)s" # 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
+ ")"
+) % {"P6": _PATT_IPV6_FRAG, "A4": _PATT_IPV4}
_ipv6_validate = {
@@ -111,11 +118,13 @@ def validate_native(cls, value):
_Ipv6Base = Unicode(45, pattern=_PATT_IPV6)
+
+
class Ipv6Address(_Ipv6Base):
"""Unicode subclass for an IPv6 address."""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'addr_ipv6'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "addr_ipv6"
class Attributes(_Ipv6Base.Attributes):
serialize_as = None
@@ -139,11 +148,13 @@ def validate_native(cls, value):
_IpAddressBase = Unicode(45, pattern=_PATT_IPV4V6)
+
+
class IpAddress(_IpAddressBase):
"""Unicode subclass for an IPv4 or IPv6 address."""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'addr_ip'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "addr_ip"
class Attributes(_IpAddressBase.Attributes):
serialize_as = None
diff --git a/spyne/model/primitive/number.py b/spyne/model/primitive/number.py
index d78cae7de..9cd76dba1 100644
--- a/spyne/model/primitive/number.py
+++ b/spyne/model/primitive/number.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -17,14 +16,14 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
-import math
import decimal
+import math
import platform
+
from _warnings import warn
from spyne.model import SimpleModel
from spyne.model.primitive import NATIVE_MAP
-from spyne.util import six
class NumberLimitsWarning(Warning):
@@ -42,7 +41,7 @@ class Decimal(SimpleModel):
documentation for more information.
"""
- __type_name__ = 'decimal'
+ __type_name__ = "decimal"
Value = decimal.Decimal
# contrary to popular belief, Decimal hates float.
@@ -51,16 +50,16 @@ class Attributes(SimpleModel.Attributes):
"""Customizable attributes of the :class:`spyne.model.primitive.Decimal`
type."""
- gt = decimal.Decimal('-inf') # minExclusive
+ gt = decimal.Decimal("-inf") # minExclusive
"""The value should be greater than this number."""
- ge = decimal.Decimal('-inf') # minInclusive
+ ge = decimal.Decimal("-inf") # minInclusive
"""The value should be greater than or equal to this number."""
- lt = decimal.Decimal('inf') # maxExclusive
+ lt = decimal.Decimal("inf") # maxExclusive
"""The value should be lower than this number."""
- le = decimal.Decimal('inf') # maxInclusive
+ le = decimal.Decimal("inf") # maxInclusive
"""The value should be lower than or equal to this number."""
max_str_len = 1024
@@ -79,10 +78,10 @@ class Attributes(SimpleModel.Attributes):
"""A regular expression that matches the whole field. See here for more
info: http://www.regular-expressions.info/xml.html"""
- total_digits = decimal.Decimal('inf')
+ total_digits = decimal.Decimal("inf")
"""Maximum number of digits."""
- fraction_digits = decimal.Decimal('inf')
+ fraction_digits = decimal.Decimal("inf")
"""Maximum number of digits after the decimal separator."""
min_bound = None
@@ -97,10 +96,10 @@ def __new__(cls, *args, **kwargs):
assert len(args) <= 2
if len(args) >= 1 and args[0] is not None:
- kwargs['total_digits'] = args[0]
- kwargs['fraction_digits'] = 0
+ kwargs["total_digits"] = args[0]
+ kwargs["fraction_digits"] = 0
if len(args) == 2 and args[1] is not None:
- kwargs['fraction_digits'] = args[1]
+ kwargs["fraction_digits"] = args[1]
retval = SimpleModel.__new__(cls, **kwargs)
@@ -108,23 +107,24 @@ def __new__(cls, *args, **kwargs):
@classmethod
def _s_customize(cls, **kwargs):
- td = kwargs.get('total_digits', None)
- fd = kwargs.get('fraction_digits', None)
+ td = kwargs.get("total_digits", None)
+ fd = kwargs.get("fraction_digits", None)
if td is not None and fd is not None:
assert td > 0, "'total_digits' must be positive."
- assert fd <= td, \
- "'total_digits' must be greater than" \
- " or equal to 'fraction_digits'." \
- " %r ! <= %r" % (fd, td)
+ assert fd <= td, (
+ "'total_digits' must be greater than"
+ " or equal to 'fraction_digits'."
+ " %r ! <= %r" % (fd, td)
+ )
- msl = kwargs.get('max_str_len', None)
+ msl = kwargs.get("max_str_len", None)
if msl is None:
- kwargs['max_str_len'] = cls.Attributes.total_digits + 2
+ kwargs["max_str_len"] = cls.Attributes.total_digits + 2
# + 1 for decimal separator
# + 1 for negative sign
else:
- kwargs['max_str_len'] = msl
+ kwargs["max_str_len"] = msl
minb = cls.Attributes.min_bound
maxb = cls.Attributes.max_bound
@@ -135,56 +135,67 @@ def _s_customize(cls, **kwargs):
if minb is not None:
if ge is not None and ge < minb:
- warn("'Greater than or equal value' %d smaller than min_bound %d"
- % (ge, minb), NumberLimitsWarning)
+ warn(
+ "'Greater than or equal value' %d smaller than min_bound %d"
+ % (ge, minb),
+ NumberLimitsWarning,
+ )
if gt is not None and gt < minb:
- warn("'Greater than' value %d smaller than min_bound %d"
- % (gt, minb), NumberLimitsWarning)
+ warn(
+ "'Greater than' value %d smaller than min_bound %d" % (gt, minb),
+ NumberLimitsWarning,
+ )
if le is not None and le < minb:
raise ValueError(
"'Little than or equal' value %d smaller than min_bound %d"
- % (le, minb))
+ % (le, minb)
+ )
if lt is not None and lt <= minb:
raise ValueError(
- "'Little than' value %d smaller than min_bound %d"
- % (lt, minb))
+ "'Little than' value %d smaller than min_bound %d" % (lt, minb)
+ )
if maxb is not None:
if le is not None and le > maxb:
- warn("'Little than or equal' value %d greater than max_bound %d"
- % (le, maxb), NumberLimitsWarning)
+ warn(
+ "'Little than or equal' value %d greater than max_bound %d"
+ % (le, maxb),
+ NumberLimitsWarning,
+ )
if lt is not None and lt > maxb:
- warn("'Little than' value %d greater than max_bound %d"
- % (lt, maxb), NumberLimitsWarning)
+ warn(
+ "'Little than' value %d greater than max_bound %d" % (lt, maxb),
+ NumberLimitsWarning,
+ )
if ge is not None and ge > maxb:
raise ValueError(
"'Greater than or equal' value %d greater than max_bound %d"
- % (ge, maxb))
+ % (ge, maxb)
+ )
if gt is not None and gt >= maxb:
raise ValueError(
- "'Greater than' value %d greater than max_bound %d"
- % (gt, maxb))
+ "'Greater than' value %d greater than max_bound %d" % (gt, maxb)
+ )
return super(Decimal, cls)._s_customize(**kwargs)
@staticmethod
def is_default(cls):
- return ( SimpleModel.is_default(cls)
- and cls.Attributes.gt == Decimal.Attributes.gt
- and cls.Attributes.ge == Decimal.Attributes.ge
- and cls.Attributes.lt == Decimal.Attributes.lt
- and cls.Attributes.le == Decimal.Attributes.le
- and cls.Attributes.total_digits ==
- Decimal.Attributes.total_digits
- and cls.Attributes.fraction_digits ==
- Decimal.Attributes.fraction_digits
- )
+ return (
+ SimpleModel.is_default(cls)
+ and cls.Attributes.gt == Decimal.Attributes.gt
+ and cls.Attributes.ge == Decimal.Attributes.ge
+ and cls.Attributes.lt == Decimal.Attributes.lt
+ and cls.Attributes.le == Decimal.Attributes.le
+ and cls.Attributes.total_digits == Decimal.Attributes.total_digits
+ and cls.Attributes.fraction_digits == Decimal.Attributes.fraction_digits
+ )
@staticmethod
def validate_string(cls, value):
@@ -195,12 +206,14 @@ def validate_string(cls, value):
@staticmethod
def validate_native(cls, value):
return SimpleModel.validate_native(cls, value) and (
- value is None or (
- value > cls.Attributes.gt and
- value >= cls.Attributes.ge and
- value < cls.Attributes.lt and
- value <= cls.Attributes.le
- ))
+ value is None
+ or (
+ value > cls.Attributes.gt
+ and value >= cls.Attributes.ge
+ and value < cls.Attributes.lt
+ and value <= cls.Attributes.le
+ )
+ )
class Double(Decimal):
@@ -217,68 +230,68 @@ class Double(Decimal):
return instances of types compatible with designated types.
"""
- __type_name__ = 'double'
+ __type_name__ = "double"
Value = float
- if platform.python_version_tuple()[:2] == ('2','6'):
+ if platform.python_version_tuple()[:2] == ("2", "6"):
+
class Attributes(Decimal.Attributes):
"""Customizable attributes of the :class:`spyne.model.primitive.Double`
type. This class is only here for Python 2.6: See this bug report
for more info: http://bugs.python.org/issue2531
"""
- gt = float('-inf') # minExclusive
+ gt = float("-inf") # minExclusive
"""The value should be greater than this number."""
- ge = float('-inf') # minInclusive
+ ge = float("-inf") # minInclusive
"""The value should be greater than or equal to this number."""
- lt = float('inf') # maxExclusive
+ lt = float("inf") # maxExclusive
"""The value should be lower than this number."""
- le = float('inf') # maxInclusive
+ le = float("inf") # maxInclusive
"""The value should be lower than or equal to this number."""
@staticmethod
def is_default(cls):
- return ( SimpleModel.is_default(cls)
- and cls.Attributes.gt == Double.Attributes.gt
- and cls.Attributes.ge == Double.Attributes.ge
- and cls.Attributes.lt == Double.Attributes.lt
- and cls.Attributes.le == Double.Attributes.le
- )
+ return (
+ SimpleModel.is_default(cls)
+ and cls.Attributes.gt == Double.Attributes.gt
+ and cls.Attributes.ge == Double.Attributes.ge
+ and cls.Attributes.lt == Double.Attributes.lt
+ and cls.Attributes.le == Double.Attributes.le
+ )
class Float(Double):
"""Synonym for Double (as far as python side of things are concerned).
It's here for compatibility reasons."""
- __type_name__ = 'float'
+ __type_name__ = "float"
class Integer(Decimal):
"""The arbitrary-size signed integer."""
- __type_name__ = 'integer'
+ __type_name__ = "integer"
Value = int
@staticmethod
def validate_native(cls, value):
- return ( Decimal.validate_native(cls, value)
- and (value is None or int(value) == value)
- )
+ return Decimal.validate_native(cls, value) and (
+ value is None or int(value) == value
+ )
class UnsignedInteger(Integer):
"""The arbitrary-size unsigned integer, also known as nonNegativeInteger."""
- __type_name__ = 'nonNegativeInteger'
+ __type_name__ = "nonNegativeInteger"
@staticmethod
def validate_native(cls, value):
- return ( Integer.validate_native(cls, value)
- and (value is None or value >= 0)
- )
+ return Integer.validate_native(cls, value) and (value is None or value >= 0)
NonNegativeInteger = UnsignedInteger
@@ -286,20 +299,18 @@ def validate_native(cls, value):
class PositiveInteger(NonNegativeInteger):
-
"""The arbitrary-size positive integer (natural number)."""
- __type_name__ = 'positiveInteger'
+ __type_name__ = "positiveInteger"
@staticmethod
def validate_native(cls, value):
- return (Integer.validate_native(cls, value)
- and (value is None or value > 0))
+ return Integer.validate_native(cls, value) and (value is None or value > 0)
def TBoundedInteger(num_bits, type_name):
- _min_b = -(0x8<<(num_bits-4)) # 0x8 is 4 bits.
- _max_b = (0x8<<(num_bits-4)) - 1 # -1? c'est la vie
+ _min_b = -(0x8 << (num_bits - 4)) # 0x8 is 4 bits.
+ _max_b = (0x8 << (num_bits - 4)) - 1 # -1? c'est la vie
class _BoundedInteger(Integer):
__type_name__ = type_name
@@ -311,9 +322,8 @@ class Attributes(Integer.Attributes):
@staticmethod
def validate_native(cls, value):
- return (
- Integer.validate_native(cls, value)
- and (value is None or (_min_b <= value <= _max_b))
+ return Integer.validate_native(cls, value) and (
+ value is None or (_min_b <= value <= _max_b)
)
return _BoundedInteger
@@ -321,7 +331,7 @@ def validate_native(cls, value):
def TBoundedUnsignedInteger(num_bits, type_name):
_min_b = 0
- _max_b = 2 ** num_bits - 1 # -1? c'est la vie ;)
+ _max_b = 2**num_bits - 1 # -1? c'est la vie ;)
class _BoundedUnsignedInteger(UnsignedInteger):
__type_name__ = type_name
@@ -333,87 +343,79 @@ class Attributes(UnsignedInteger.Attributes):
@staticmethod
def validate_native(cls, value):
- return (
- UnsignedInteger.validate_native(cls, value)
- and (value is None or (_min_b <= value < _max_b))
+ return UnsignedInteger.validate_native(cls, value) and (
+ value is None or (_min_b <= value < _max_b)
)
return _BoundedUnsignedInteger
-Integer64 = TBoundedInteger(64, 'long')
+Integer64 = TBoundedInteger(64, "long")
"""The 64-bit signed integer, also known as ``long``."""
Long = Integer64
"""The 64-bit signed integer, alias for :class:`Integer64`."""
-Integer32 = TBoundedInteger(32, 'int')
+Integer32 = TBoundedInteger(32, "int")
"""The 64-bit signed integer, also known as ``int``."""
Int = Integer32
"""The 32-bit signed integer, alias for :class:`Integer32`."""
-Integer16 = TBoundedInteger(16, 'short')
+Integer16 = TBoundedInteger(16, "short")
"""The 16-bit signed integer, also known as ``short``."""
Short = Integer16
"""The 16-bit signed integer, alias for :class:`Integer16`."""
-Integer8 = TBoundedInteger(8, 'byte')
+Integer8 = TBoundedInteger(8, "byte")
"""The 8-bit signed integer, also known as ``byte``."""
Byte = Integer8
"""The 8-bit signed integer, alias for :class:`Integer8`."""
-UnsignedInteger64 = TBoundedUnsignedInteger(64, 'unsignedLong')
+UnsignedInteger64 = TBoundedUnsignedInteger(64, "unsignedLong")
"""The 64-bit unsigned integer, also known as ``unsignedLong``."""
UnsignedLong = UnsignedInteger64
"""The 64-bit unsigned integer, alias for :class:`UnsignedInteger64`."""
-UnsignedInteger32 = TBoundedUnsignedInteger(32, 'unsignedInt')
+UnsignedInteger32 = TBoundedUnsignedInteger(32, "unsignedInt")
"""The 64-bit unsigned integer, also known as ``unsignedInt``."""
UnsignedInt = UnsignedInteger32
"""The 32-bit unsigned integer, alias for :class:`UnsignedInteger32`."""
-UnsignedInteger16 = TBoundedUnsignedInteger(16, 'unsignedShort')
+UnsignedInteger16 = TBoundedUnsignedInteger(16, "unsignedShort")
"""The 16-bit unsigned integer, also known as ``unsignedShort``."""
UnsignedShort = UnsignedInteger16
"""The 16-bit unsigned integer, alias for :class:`UnsignedInteger16`."""
-UnsignedInteger8 = TBoundedUnsignedInteger(8, 'unsignedByte')
+UnsignedInteger8 = TBoundedUnsignedInteger(8, "unsignedByte")
"""The 8-bit unsigned integer, also known as ``unsignedByte``."""
UnsignedByte = UnsignedInteger8
"""The 8-bit unsigned integer, alias for :class:`UnsignedInteger8`."""
-NATIVE_MAP.update({
- float: Double,
- decimal.Decimal: Decimal,
-})
+NATIVE_MAP.update(
+ {
+ float: Double,
+ decimal.Decimal: Decimal,
+ }
+)
-if not six.PY2:
- NATIVE_MAP.update({
+NATIVE_MAP.update(
+ {
int: Integer,
- })
-
-else:
- NATIVE_MAP.update({
- long: Integer,
- })
-
- if isinstance(0x80000000, long): # 32-bit architecture
- NATIVE_MAP[int] = Integer32
- else: # not 32-bit (so most probably 64-bit) architecture
- NATIVE_MAP[int] = Integer64
+ }
+)
diff --git a/spyne/model/primitive/spatial.py b/spyne/model/primitive/spatial.py
index cf3ada5e9..139bb1075 100644
--- a/spyne/model/primitive/spatial.py
+++ b/spyne/model/primitive/spatial.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -27,53 +26,63 @@
from spyne.model import SimpleModel
from spyne.model.primitive.string import Unicode
+FLOAT_PATTERN = r"-?[0-9]+\.?[0-9]*(e-?[0-9]+)?"
+
-FLOAT_PATTERN = r'-?[0-9]+\.?[0-9]*(e-?[0-9]+)?'
+_rinse_and_repeat = r"\s*\(%s\s*(,\s*%s)*\)\s*"
-_rinse_and_repeat = r'\s*\(%s\s*(,\s*%s)*\)\s*'
def _get_one_point_pattern(dim):
- return ' +'.join([FLOAT_PATTERN] * dim)
+ return " +".join([FLOAT_PATTERN] * dim)
+
def _get_point_pattern(dim):
- return r'POINT\s*\(%s\)' % _get_one_point_pattern(dim)
+ return r"POINT\s*\(%s\)" % _get_one_point_pattern(dim)
+
def _get_one_multipoint_pattern(dim):
one_point = _get_one_point_pattern(dim)
return _rinse_and_repeat % (one_point, one_point)
+
def _get_multipoint_pattern(dim):
- return r'MULTIPOINT%s' % _get_one_multipoint_pattern(dim)
+ return r"MULTIPOINT%s" % _get_one_multipoint_pattern(dim)
def _get_one_line_pattern(dim):
one_point = _get_one_point_pattern(dim)
return _rinse_and_repeat % (one_point, one_point)
+
def _get_linestring_pattern(dim):
- return r'LINESTRING%s' % _get_one_line_pattern(dim)
+ return r"LINESTRING%s" % _get_one_line_pattern(dim)
+
def _get_one_multilinestring_pattern(dim):
one_line = _get_one_line_pattern(dim)
return _rinse_and_repeat % (one_line, one_line)
+
def _get_multilinestring_pattern(dim):
- return r'MULTILINESTRING%s' % _get_one_multilinestring_pattern(dim)
+ return r"MULTILINESTRING%s" % _get_one_multilinestring_pattern(dim)
def _get_one_polygon_pattern(dim):
one_line = _get_one_line_pattern(dim)
return _rinse_and_repeat % (one_line, one_line)
+
def _get_polygon_pattern(dim):
- return r'POLYGON%s' % _get_one_polygon_pattern(dim)
+ return r"POLYGON%s" % _get_one_polygon_pattern(dim)
+
def _get_one_multipolygon_pattern(dim):
one_line = _get_one_polygon_pattern(dim)
return _rinse_and_repeat % (one_line, one_line)
+
def _get_multipolygon_pattern(dim):
- return r'MULTIPOLYGON%s' % _get_one_multipolygon_pattern(dim)
+ return r"MULTIPOLYGON%s" % _get_one_multipolygon_pattern(dim)
class Point(Unicode):
@@ -96,19 +105,19 @@ def Value(x, y, prec=15):
if isinstance(x, str) or isinstance(y, str):
assert isinstance(x, str)
assert isinstance(y, str)
- return 'POINT(%s %s)' % (x, y)
+ return "POINT(%s %s)" % (x, y)
- return ('POINT(%%3.%(prec)sf %%3.%(prec)sf)' % {'prec': prec}) % (x,y)
+ return ("POINT(%%3.%(prec)sf %%3.%(prec)sf)" % {"prec": prec}) % (x, y)
def __new__(cls, dim=None, **kwargs):
assert dim in (None, 2, 3)
if dim is not None:
- kwargs['dim'] = dim
- kwargs['pattern'] = _get_point_pattern(dim)
- kwargs['type_name'] = 'point%dd' % dim
+ kwargs["dim"] = dim
+ kwargs["pattern"] = _get_point_pattern(dim)
+ kwargs["type_name"] = "point%dd" % dim
retval = SimpleModel.__new__(cls, **kwargs)
- retval.__namespace__ = 'http://spyne.io/schema'
+ retval.__namespace__ = "http://spyne.io/schema"
retval.__extends__ = Unicode
retval.__orig__ = Unicode
return retval
@@ -132,16 +141,17 @@ class Attributes(Unicode.Attributes):
def __new__(cls, dim=None, **kwargs):
assert dim in (None, 2, 3)
if dim is not None:
- kwargs['dim'] = dim
- kwargs['pattern'] = _get_linestring_pattern(dim)
- kwargs['type_name'] = 'line%dd' % dim
+ kwargs["dim"] = dim
+ kwargs["pattern"] = _get_linestring_pattern(dim)
+ kwargs["type_name"] = "line%dd" % dim
retval = SimpleModel.__new__(cls, **kwargs)
- retval.__namespace__ = 'http://spyne.io/schema'
+ retval.__namespace__ = "http://spyne.io/schema"
retval.__extends__ = Unicode
retval.__orig__ = Unicode
return retval
+
LineString = Line
@@ -154,6 +164,7 @@ class Polygon(Unicode):
:param dim: Number of dimensons.
"""
+
__type_name__ = None
class Attributes(Unicode.Attributes):
@@ -162,12 +173,12 @@ class Attributes(Unicode.Attributes):
def __new__(cls, dim=None, **kwargs):
assert dim in (None, 2, 3)
if dim is not None:
- kwargs['dim'] = dim
- kwargs['pattern'] = _get_polygon_pattern(dim)
- kwargs['type_name'] = 'polygon%dd' % dim
+ kwargs["dim"] = dim
+ kwargs["pattern"] = _get_polygon_pattern(dim)
+ kwargs["type_name"] = "polygon%dd" % dim
retval = SimpleModel.__new__(cls, **kwargs)
- retval.__namespace__ = 'http://spyne.io/schema'
+ retval.__namespace__ = "http://spyne.io/schema"
retval.__extends__ = Unicode
retval.__orig__ = Unicode
return retval
@@ -191,12 +202,12 @@ class Attributes(Unicode.Attributes):
def __new__(cls, dim=None, **kwargs):
assert dim in (None, 2, 3)
if dim is not None:
- kwargs['dim'] = dim
- kwargs['pattern'] = _get_multipoint_pattern(dim)
- kwargs['type_name'] = 'multiPoint%dd' % dim
+ kwargs["dim"] = dim
+ kwargs["pattern"] = _get_multipoint_pattern(dim)
+ kwargs["type_name"] = "multiPoint%dd" % dim
retval = SimpleModel.__new__(cls, **kwargs)
- retval.__namespace__ = 'http://spyne.io/schema'
+ retval.__namespace__ = "http://spyne.io/schema"
retval.__extends__ = Unicode
retval.__orig__ = Unicode
return retval
@@ -220,16 +231,17 @@ class Attributes(Unicode.Attributes):
def __new__(cls, dim=None, **kwargs):
assert dim in (None, 2, 3)
if dim is not None:
- kwargs['dim'] = dim
- kwargs['pattern'] = _get_multilinestring_pattern(dim)
- kwargs['type_name'] = 'multiLine%dd' % dim
+ kwargs["dim"] = dim
+ kwargs["pattern"] = _get_multilinestring_pattern(dim)
+ kwargs["type_name"] = "multiLine%dd" % dim
retval = SimpleModel.__new__(cls, **kwargs)
- retval.__namespace__ = 'http://spyne.io/schema'
+ retval.__namespace__ = "http://spyne.io/schema"
retval.__extends__ = Unicode
retval.__orig__ = Unicode
return retval
+
MultiLineString = MultiLine
@@ -251,13 +263,12 @@ class Attributes(Unicode.Attributes):
def __new__(cls, dim=None, **kwargs):
assert dim in (None, 2, 3)
if dim is not None:
- kwargs['dim'] = dim
- kwargs['pattern'] = _get_multipolygon_pattern(dim)
- kwargs['type_name'] = 'multipolygon%dd' % dim
+ kwargs["dim"] = dim
+ kwargs["pattern"] = _get_multipolygon_pattern(dim)
+ kwargs["type_name"] = "multipolygon%dd" % dim
retval = SimpleModel.__new__(cls, **kwargs)
- retval.__namespace__ = 'http://spyne.io/schema'
+ retval.__namespace__ = "http://spyne.io/schema"
retval.__extends__ = Unicode
retval.__orig__ = Unicode
return retval
-
diff --git a/spyne/model/primitive/string.py b/spyne/model/primitive/string.py
index 6253fef71..e721fda36 100644
--- a/spyne/model/primitive/string.py
+++ b/spyne/model/primitive/string.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -22,14 +21,11 @@
import decimal
import uuid
-from spyne.model.primitive import NATIVE_MAP
-from spyne.util import six
from spyne.model._base import SimpleModel
+from spyne.model.primitive import NATIVE_MAP
from spyne.model.primitive._base import re_match_with_span
-
-UUID_PATTERN = "%(x)s{8}-%(x)s{4}-%(x)s{4}-%(x)s{4}-%(x)s{12}" % \
- {'x': '[a-fA-F0-9]'}
+UUID_PATTERN = "%(x)s{8}-%(x)s{4}-%(x)s{4}-%(x)s{4}-%(x)s{12}" % {"x": "[a-fA-F0-9]"}
LTREE_PATTERN = r"\w+(\.\w+)*"
@@ -38,17 +34,17 @@
LTREE_MAXIMUM_SIZE = 65536
-'[0-9A-Za-z!#$%&\'*+.^_`|~-]+/([0-9A-Za-z!#$%&\'*+.^_`|~-]+);[ \\t]*[0-9A-Za-z!#$%&\'*+.^_`|~-]+=(?:[0-9A-Za-z!#$%&\'*+.^_`|~-]+|"(?:[^"\\\\]|\\.)*");?[ \\t]*([0-9A-Za-z!#$%&\'*+.^_`|~-]+=(?:[0-9A-Za-z!#$%&\'*+.^_`|~-]+|"(?:[^"\\\\]|\\.)*");?[ \\t]*)*'
-
def _gen_mime_type_pattern(strict, with_params):
ows = "[ \\t]*" # Optional WhiteSpace
token = "[0-9A-Za-z!#$%&'*+.^_`|~-]+"
- quotedString = "\"(?:[^\"\\\\]|\\.)*\""
+ quotedString = '"(?:[^"\\\\]|\\.)*"'
if strict:
- main_type = "(" \
- "application|audio|font|example|image|message|model|multipart" \
- "|text|video|x-(?:" + token + ")" \
+ main_type = (
+ "("
+ "application|audio|font|example|image|message|model|multipart"
+ "|text|video|x-(?:" + token + ")"
")"
+ )
else:
main_type = token
@@ -57,23 +53,16 @@ def _gen_mime_type_pattern(strict, with_params):
return main_type + "/" + "(" + token + ")"
param = token + "=" + "(?:" + token + "|" + quotedString + ");?" + ows
- params = \
- "(" + ";" \
- + "(" + ows + param + "(" + param + ")*" + ")?" \
- + ")?"
+ params = "(" + ";" + "(" + ows + param + "(" + param + ")*" + ")?" + ")?"
return main_type + "/" + "(" + token + ")" + params
-MIME_TYPE_PATTERN_STRICT = \
- _gen_mime_type_pattern(strict=True, with_params=False)
-MIME_TYPE_PATTERN_PERMISSIVE = \
- _gen_mime_type_pattern(strict=False, with_params=False)
+MIME_TYPE_PATTERN_STRICT = _gen_mime_type_pattern(strict=True, with_params=False)
+MIME_TYPE_PATTERN_PERMISSIVE = _gen_mime_type_pattern(strict=False, with_params=False)
-MEDIA_TYPE_PATTERN_STRICT = \
- _gen_mime_type_pattern(strict=True, with_params=True)
-MEDIA_TYPE_PATTERN_PERMISSIVE = \
- _gen_mime_type_pattern(strict=False, with_params=True)
+MEDIA_TYPE_PATTERN_STRICT = _gen_mime_type_pattern(strict=True, with_params=True)
+MEDIA_TYPE_PATTERN_PERMISSIVE = _gen_mime_type_pattern(strict=False, with_params=True)
class Unicode(SimpleModel):
@@ -81,8 +70,8 @@ class Unicode(SimpleModel):
or `str` with given encoding.
"""
- __type_name__ = 'string'
- Value = six.text_type
+ __type_name__ = "string"
+ Value = str
class Attributes(SimpleModel.Attributes):
"""Customizable attributes of the :class:`spyne.model.primitive.Unicode`
@@ -91,7 +80,7 @@ class Attributes(SimpleModel.Attributes):
min_len = 0
"""Minimum length of string. Can be set to any positive integer"""
- max_len = decimal.Decimal('inf')
+ max_len = decimal.Decimal("inf")
"""Maximum length of string. Can be set to ``decimal.Decimal('inf')`` to
accept strings of arbitrary length. You may also need to adjust
:const:`spyne.server.wsgi.MAX_CONTENT_LENGTH`."""
@@ -107,7 +96,7 @@ class Attributes(SimpleModel.Attributes):
encoding = None
"""The encoding of binary data this class may have to deal with."""
- unicode_errors = 'strict'
+ unicode_errors = "strict"
"""The argument to the ``unicode`` builtin; one of 'strict', 'replace'
or 'ignore'."""
@@ -122,46 +111,46 @@ def __new__(cls, *args, **kwargs):
assert len(args) <= 1
if len(args) == 1:
- kwargs['max_len'] = args[0]
+ kwargs["max_len"] = args[0]
- retval = SimpleModel.__new__(cls, ** kwargs)
+ retval = SimpleModel.__new__(cls, **kwargs)
return retval
@staticmethod
def is_default(cls):
- return ( SimpleModel.is_default(cls)
- and cls.Attributes.min_len == Unicode.Attributes.min_len
- and cls.Attributes.max_len == Unicode.Attributes.max_len
- and cls.Attributes.pattern == Unicode.Attributes.pattern
- )
+ return (
+ SimpleModel.is_default(cls)
+ and cls.Attributes.min_len == Unicode.Attributes.min_len
+ and cls.Attributes.max_len == Unicode.Attributes.max_len
+ and cls.Attributes.pattern == Unicode.Attributes.pattern
+ )
@staticmethod
def validate_string(cls, value):
- return ( SimpleModel.validate_string(cls, value)
- and (value is None or (
- cls.Attributes.min_len <= len(value) <= cls.Attributes.max_len
- )))
+ return SimpleModel.validate_string(cls, value) and (
+ value is None
+ or (cls.Attributes.min_len <= len(value) <= cls.Attributes.max_len)
+ )
@staticmethod
def validate_native(cls, value):
- return (SimpleModel.validate_native(cls, value)
- and (value is None or (
- re_match_with_span(cls.Attributes, value)
- )))
+ return SimpleModel.validate_native(cls, value) and (
+ value is None or (re_match_with_span(cls.Attributes, value))
+ )
class String(Unicode):
pass
-if not six.PY2:
- String = Unicode
+
+String = Unicode
class AnyUri(Unicode):
"""A special kind of String type designed to hold an uri."""
- __type_name__ = 'anyURI'
+ __type_name__ = "anyURI"
class Attributes(String.Attributes):
text = None
@@ -187,8 +176,9 @@ def __init__(self, href, text=None, content=None):
self.content = content
def __repr__(self):
- return "Uri(href={0!r}, text={1!r}, content={2!r})" \
- .format(self.href, self.text, self.content)
+ return "Uri(href={0!r}, text={1!r}, content={2!r})".format(
+ self.href, self.text, self.content
+ )
class ImageUri(AnyUri):
@@ -196,11 +186,13 @@ class ImageUri(AnyUri):
def _uuid_validate_string(cls, value):
- return ( SimpleModel.validate_string(cls, value)
- and (value is None or (
+ return SimpleModel.validate_string(cls, value) and (
+ value is None
+ or (
cls.Attributes.min_len <= len(value) <= cls.Attributes.max_len
and re_match_with_span(cls.Attributes, value)
- )))
+ )
+ )
def _Tuuid_validate(key):
@@ -208,31 +200,32 @@ def _Tuuid_validate(key):
def _uvalid(cls, v):
try:
- UUID(**{key:v})
+ UUID(**{key: v})
except ValueError:
return False
return True
+
return _uvalid
_uuid_validate = {
None: _uuid_validate_string,
- 'hex': _Tuuid_validate('hex'),
- 'urn': _Tuuid_validate('urn'),
- six.binary_type: _Tuuid_validate('bytes'),
- 'bytes': _Tuuid_validate('bytes'),
- 'bytes_le': _Tuuid_validate('bytes_le'),
- 'fields': _Tuuid_validate('fields'),
- int: _Tuuid_validate('int'),
- 'int': _Tuuid_validate('int'),
+ "hex": _Tuuid_validate("hex"),
+ "urn": _Tuuid_validate("urn"),
+ bytes: _Tuuid_validate("bytes"),
+ "bytes": _Tuuid_validate("bytes"),
+ "bytes_le": _Tuuid_validate("bytes_le"),
+ "fields": _Tuuid_validate("fields"),
+ int: _Tuuid_validate("int"),
+ "int": _Tuuid_validate("int"),
}
class Uuid(Unicode(pattern=UUID_PATTERN)):
"""Unicode subclass for Universially-Unique Identifiers."""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'uuid'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "uuid"
Value = uuid.UUID
class Attributes(Unicode(pattern=UUID_PATTERN).Attributes):
@@ -251,32 +244,32 @@ class Ltree(Unicode(LTREE_OPTIMAL_SIZE, unicode_pattern=LTREE_PATTERN)):
"""A special kind of String type designed to hold the Ltree type from
Postgresql."""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'ltreeString'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "ltreeString"
class LtreeLarge(Unicode(LTREE_MAXIMUM_SIZE, unicode_pattern=LTREE_PATTERN)):
"""A special kind of String type designed to hold the Ltree type from
Postgresql."""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'largeLtreeString'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "largeLtreeString"
class MimeTypeStrict(Unicode(unicode_pattern=MIME_TYPE_PATTERN_STRICT)):
"""A special kind of String type designed to hold a mime type as defined
by IANA."""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'strictMimeTypeString'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "strictMimeTypeString"
class MimeType(Unicode(unicode_pattern=MIME_TYPE_PATTERN_PERMISSIVE)):
"""A special kind of String type designed to hold a forward-compatible
mime type that can have any string as main type."""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'mimeTypeString'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "mimeTypeString"
class MediaTypeStrict(Unicode(unicode_pattern=MEDIA_TYPE_PATTERN_STRICT)):
@@ -285,8 +278,8 @@ class MediaTypeStrict(Unicode(unicode_pattern=MEDIA_TYPE_PATTERN_STRICT)):
See: https://tools.ietf.org/html/rfc7231#section-3.1.1.1"""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'strictMediaTypeString'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "strictMediaTypeString"
class MediaType(Unicode(unicode_pattern=MEDIA_TYPE_PATTERN_PERMISSIVE)):
@@ -296,17 +289,12 @@ class MediaType(Unicode(unicode_pattern=MEDIA_TYPE_PATTERN_PERMISSIVE)):
See: https://tools.ietf.org/html/rfc7231#section-3.1.1.1"""
- __namespace__ = 'http://spyne.io/schema'
- __type_name__ = 'mediaTypeString'
+ __namespace__ = "http://spyne.io/schema"
+ __type_name__ = "mediaTypeString"
-if not six.PY2:
- NATIVE_MAP.update({
+NATIVE_MAP.update(
+ {
str: Unicode,
- })
-
-else:
- NATIVE_MAP.update({
- str: String,
- unicode: Unicode,
- })
+ }
+)
diff --git a/spyne/model/primitive/xml.py b/spyne/model/primitive/xml.py
index d60494a61..1b269ab81 100644
--- a/spyne/model/primitive/xml.py
+++ b/spyne/model/primitive/xml.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -22,108 +21,135 @@
from spyne.const.xml import PATT_NMTOKEN
from spyne.model.primitive.string import Unicode
-
RE_BaseChar = re.compile(
- u"[\u0041-\u005A]|[\u0061-\u007A]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|"
- u"[\u00F8-\u00FF]|[\u0100-\u0131]|[\u0134-\u013E]|[\u0141-\u0148]|"
- u"[\u014A-\u017E]|[\u0180-\u01C3]|[\u01CD-\u01F0]|[\u01F4-\u01F5]|"
- u"[\u01FA-\u0217]|[\u0250-\u02A8]|[\u02BB-\u02C1]|\u0386|[\u0388-\u038A]|"
- u"\u038C|[\u038E-\u03A1]|[\u03A3-\u03CE]|[\u03D0-\u03D6]|"
- u"\u03DA|\u03DC|\u03DE|\u03E0|[\u03E2-\u03F3]|[\u0401-\u040C]|"
- u"[\u040E-\u044F]|[\u0451-\u045C]|[\u045E-\u0481]|[\u0490-\u04C4]|"
- u"[\u04C7-\u04C8]|[\u04CB-\u04CC]|[\u04D0-\u04EB]|[\u04EE-\u04F5]|"
- u"[\u04F8-\u04F9]|[\u0531-\u0556]|\u0559|[\u0561-\u0586]|[\u05D0-\u05EA]|"
- u"[\u05F0-\u05F2]|[\u0621-\u063A]|[\u0641-\u064A]|[\u0671-\u06B7]|"
- u"[\u06BA-\u06BE]|[\u06C0-\u06CE]|[\u06D0-\u06D3]|\u06D5|[\u06E5-\u06E6]|"
- u"[\u0905-\u0939]|\u093D|[\u0958-\u0961]|[\u0985-\u098C]|[\u098F-\u0990]|"
- u"[\u0993-\u09A8]|[\u09AA-\u09B0]|\u09B2|[\u09B6-\u09B9]|[\u09DC-\u09DD]|"
- u"[\u09DF-\u09E1]|[\u09F0-\u09F1]|[\u0A05-\u0A0A]|[\u0A0F-\u0A10]|"
- u"[\u0A13-\u0A28]|[\u0A2A-\u0A30]|[\u0A32-\u0A33]|[\u0A35-\u0A36]|"
- u"[\u0A38-\u0A39]|[\u0A59-\u0A5C]|\u0A5E|[\u0A72-\u0A74]|[\u0A85-\u0A8B]|"
- u"\u0A8D|[\u0A8F-\u0A91]|[\u0A93-\u0AA8]|[\u0AAA-\u0AB0]|[\u0AB2-\u0AB3]|"
- u"[\u0AB5-\u0AB9]|\u0ABD|\u0AE0|[\u0B05-\u0B0C]|[\u0B0F-\u0B10]|"
- u"[\u0B13-\u0B28]|[\u0B2A-\u0B30]|[\u0B32-\u0B33]|[\u0B36-\u0B39]|\u0B3D|"
- u"[\u0B5C-\u0B5D]|[\u0B5F-\u0B61]|[\u0B85-\u0B8A]|[\u0B8E-\u0B90]|"
- u"[\u0B92-\u0B95]|[\u0B99-\u0B9A]|\u0B9C|[\u0B9E-\u0B9F]|[\u0BA3-\u0BA4]|"
- u"[\u0BA8-\u0BAA]|[\u0BAE-\u0BB5]|[\u0BB7-\u0BB9]|[\u0C05-\u0C0C]|"
- u"[\u0C0E-\u0C10]|[\u0C12-\u0C28]|[\u0C2A-\u0C33]|[\u0C35-\u0C39]|"
- u"[\u0C60-\u0C61]|[\u0C85-\u0C8C]|[\u0C8E-\u0C90]|[\u0C92-\u0CA8]|"
- u"[\u0CAA-\u0CB3]|[\u0CB5-\u0CB9]|\u0CDE|[\u0CE0-\u0CE1]|[\u0D05-\u0D0C]|"
- u"[\u0D0E-\u0D10]|[\u0D12-\u0D28]|[\u0D2A-\u0D39]|[\u0D60-\u0D61]|"
- u"[\u0E01-\u0E2E]|\u0E30|[\u0E32-\u0E33]|[\u0E40-\u0E45]|[\u0E81-\u0E82]|"
- u"\u0E84|[\u0E87-\u0E88]|\u0E8A|\u0E8D|[\u0E94-\u0E97]|[\u0E99-\u0E9F]|"
- u"[\u0EA1-\u0EA3]|\u0EA5|\u0EA7|[\u0EAA-\u0EAB]|[\u0EAD-\u0EAE]|\u0EB0|"
- u"[\u0EB2-\u0EB3]|\u0EBD|[\u0EC0-\u0EC4]|[\u0F40-\u0F47]|[\u0F49-\u0F69]|"
- u"[\u10A0-\u10C5]|[\u10D0-\u10F6]|\u1100|[\u1102-\u1103]|[\u1105-\u1107]|"
- u"\u1109|[\u110B-\u110C]|[\u110E-\u1112]|\u113C|\u113E|\u1140|\u114C|"
- u"\u114E|\u1150|[\u1154-\u1155]|\u1159|[\u115F-\u1161]|\u1163|\u1165|"
- u"\u1167|\u1169|[\u116D-\u116E]|[\u1172-\u1173]|\u1175|\u119E|\u11A8|"
- u"\u11AB|[\u11AE-\u11AF]|[\u11B7-\u11B8]|\u11BA|[\u11BC-\u11C2]|\u11EB|"
- u"\u11F0|\u11F9|[\u1E00-\u1E9B]|[\u1EA0-\u1EF9]|[\u1F00-\u1F15]|"
- u"[\u1F18-\u1F1D]|[\u1F20-\u1F45]|[\u1F48-\u1F4D]|[\u1F50-\u1F57]|\u1F59|"
- u"\u1F5B|\u1F5D|[\u1F5F-\u1F7D]|[\u1F80-\u1FB4]|[\u1FB6-\u1FBC]|\u1FBE|"
- u"[\u1FC2-\u1FC4]|[\u1FC6-\u1FCC]|[\u1FD0-\u1FD3]|[\u1FD6-\u1FDB]|"
- u"[\u1FE0-\u1FEC]|[\u1FF2-\u1FF4]|[\u1FF6-\u1FFC]|\u2126|[\u212A-\u212B]|"
- u"\u212E|[\u2180-\u2182]|[\u3041-\u3094]|[\u30A1-\u30FA]|[\u3105-\u312C]|"
- u"[\uAC00-\uD7A3]", flags=re.UNICODE)
-
-
-RE_Ideographic = re.compile(u"[\u4E00-\u9FA5]|\u3007|[\u3021-\u3029]",
- flags=re.UNICODE)
-
-RE_CombiningChar= re.compile(
- u"[\u0300-\u0345]|[\u0360-\u0361]|[\u0483-\u0486]|[\u0591-\u05A1]|"
- u"[\u05A3-\u05B9]|[\u05BB-\u05BD]|\u05BF|[\u05C1-\u05C2]|\u05C4|"
- u"[\u064B-\u0652]|\u0670|[\u06D6-\u06DC]|[\u06DD-\u06DF]|[\u06E0-\u06E4]|"
- u"[\u06E7-\u06E8]|[\u06EA-\u06ED]|[\u0901-\u0903]|\u093C|[\u093E-\u094C]|"
- u"\u094D|[\u0951-\u0954]|[\u0962-\u0963]|[\u0981-\u0983]|\u09BC|\u09BE|"
- u"\u09BF|[\u09C0-\u09C4]|[\u09C7-\u09C8]|[\u09CB-\u09CD]|\u09D7|"
- u"[\u09E2-\u09E3]|\u0A02|\u0A3C|\u0A3E|\u0A3F|[\u0A40-\u0A42]|"
- u"[\u0A47-\u0A48]|[\u0A4B-\u0A4D]|[\u0A70-\u0A71]|[\u0A81-\u0A83]|\u0ABC|"
- u"[\u0ABE-\u0AC5]|[\u0AC7-\u0AC9]|[\u0ACB-\u0ACD]|[\u0B01-\u0B03]|\u0B3C|"
- u"[\u0B3E-\u0B43]|[\u0B47-\u0B48]|[\u0B4B-\u0B4D]|[\u0B56-\u0B57]|"
- u"[\u0B82-\u0B83]|[\u0BBE-\u0BC2]|[\u0BC6-\u0BC8]|[\u0BCA-\u0BCD]|\u0BD7|"
- u"[\u0C01-\u0C03]|[\u0C3E-\u0C44]|[\u0C46-\u0C48]|[\u0C4A-\u0C4D]|"
- u"[\u0C55-\u0C56]|[\u0C82-\u0C83]|[\u0CBE-\u0CC4]|[\u0CC6-\u0CC8]|"
- u"[\u0CCA-\u0CCD]|[\u0CD5-\u0CD6]|[\u0D02-\u0D03]|[\u0D3E-\u0D43]|"
- u"[\u0D46-\u0D48]|[\u0D4A-\u0D4D]|\u0D57|\u0E31|[\u0E34-\u0E3A]|"
- u"[\u0E47-\u0E4E]|\u0EB1|[\u0EB4-\u0EB9]|[\u0EBB-\u0EBC]|[\u0EC8-\u0ECD]|"
- u"[\u0F18-\u0F19]|\u0F35|\u0F37|\u0F39|\u0F3E|\u0F3F|[\u0F71-\u0F84]|"
- u"[\u0F86-\u0F8B]|[\u0F90-\u0F95]|\u0F97|[\u0F99-\u0FAD]|[\u0FB1-\u0FB7]|"
- u"\u0FB9|[\u20D0-\u20DC]|\u20E1|[\u302A-\u302F]|\u3099|\u309A",
- flags=re.UNICODE)
+ "[\u0041-\u005a]|[\u0061-\u007a]|[\u00c0-\u00d6]|[\u00d8-\u00f6]|"
+ "[\u00f8-\u00ff]|[\u0100-\u0131]|[\u0134-\u013e]|[\u0141-\u0148]|"
+ "[\u014a-\u017e]|[\u0180-\u01c3]|[\u01cd-\u01f0]|[\u01f4-\u01f5]|"
+ "[\u01fa-\u0217]|[\u0250-\u02a8]|[\u02bb-\u02c1]|\u0386|[\u0388-\u038a]|"
+ "\u038c|[\u038e-\u03a1]|[\u03a3-\u03ce]|[\u03d0-\u03d6]|"
+ "\u03da|\u03dc|\u03de|\u03e0|[\u03e2-\u03f3]|[\u0401-\u040c]|"
+ "[\u040e-\u044f]|[\u0451-\u045c]|[\u045e-\u0481]|[\u0490-\u04c4]|"
+ "[\u04c7-\u04c8]|[\u04cb-\u04cc]|[\u04d0-\u04eb]|[\u04ee-\u04f5]|"
+ "[\u04f8-\u04f9]|[\u0531-\u0556]|\u0559|[\u0561-\u0586]|[\u05d0-\u05ea]|"
+ "[\u05f0-\u05f2]|[\u0621-\u063a]|[\u0641-\u064a]|[\u0671-\u06b7]|"
+ "[\u06ba-\u06be]|[\u06c0-\u06ce]|[\u06d0-\u06d3]|\u06d5|[\u06e5-\u06e6]|"
+ "[\u0905-\u0939]|\u093d|[\u0958-\u0961]|[\u0985-\u098c]|[\u098f-\u0990]|"
+ "[\u0993-\u09a8]|[\u09aa-\u09b0]|\u09b2|[\u09b6-\u09b9]|[\u09dc-\u09dd]|"
+ "[\u09df-\u09e1]|[\u09f0-\u09f1]|[\u0a05-\u0a0a]|[\u0a0f-\u0a10]|"
+ "[\u0a13-\u0a28]|[\u0a2a-\u0a30]|[\u0a32-\u0a33]|[\u0a35-\u0a36]|"
+ "[\u0a38-\u0a39]|[\u0a59-\u0a5c]|\u0a5e|[\u0a72-\u0a74]|[\u0a85-\u0a8b]|"
+ "\u0a8d|[\u0a8f-\u0a91]|[\u0a93-\u0aa8]|[\u0aaa-\u0ab0]|[\u0ab2-\u0ab3]|"
+ "[\u0ab5-\u0ab9]|\u0abd|\u0ae0|[\u0b05-\u0b0c]|[\u0b0f-\u0b10]|"
+ "[\u0b13-\u0b28]|[\u0b2a-\u0b30]|[\u0b32-\u0b33]|[\u0b36-\u0b39]|\u0b3d|"
+ "[\u0b5c-\u0b5d]|[\u0b5f-\u0b61]|[\u0b85-\u0b8a]|[\u0b8e-\u0b90]|"
+ "[\u0b92-\u0b95]|[\u0b99-\u0b9a]|\u0b9c|[\u0b9e-\u0b9f]|[\u0ba3-\u0ba4]|"
+ "[\u0ba8-\u0baa]|[\u0bae-\u0bb5]|[\u0bb7-\u0bb9]|[\u0c05-\u0c0c]|"
+ "[\u0c0e-\u0c10]|[\u0c12-\u0c28]|[\u0c2a-\u0c33]|[\u0c35-\u0c39]|"
+ "[\u0c60-\u0c61]|[\u0c85-\u0c8c]|[\u0c8e-\u0c90]|[\u0c92-\u0ca8]|"
+ "[\u0caa-\u0cb3]|[\u0cb5-\u0cb9]|\u0cde|[\u0ce0-\u0ce1]|[\u0d05-\u0d0c]|"
+ "[\u0d0e-\u0d10]|[\u0d12-\u0d28]|[\u0d2a-\u0d39]|[\u0d60-\u0d61]|"
+ "[\u0e01-\u0e2e]|\u0e30|[\u0e32-\u0e33]|[\u0e40-\u0e45]|[\u0e81-\u0e82]|"
+ "\u0e84|[\u0e87-\u0e88]|\u0e8a|\u0e8d|[\u0e94-\u0e97]|[\u0e99-\u0e9f]|"
+ "[\u0ea1-\u0ea3]|\u0ea5|\u0ea7|[\u0eaa-\u0eab]|[\u0ead-\u0eae]|\u0eb0|"
+ "[\u0eb2-\u0eb3]|\u0ebd|[\u0ec0-\u0ec4]|[\u0f40-\u0f47]|[\u0f49-\u0f69]|"
+ "[\u10a0-\u10c5]|[\u10d0-\u10f6]|\u1100|[\u1102-\u1103]|[\u1105-\u1107]|"
+ "\u1109|[\u110b-\u110c]|[\u110e-\u1112]|\u113c|\u113e|\u1140|\u114c|"
+ "\u114e|\u1150|[\u1154-\u1155]|\u1159|[\u115f-\u1161]|\u1163|\u1165|"
+ "\u1167|\u1169|[\u116d-\u116e]|[\u1172-\u1173]|\u1175|\u119e|\u11a8|"
+ "\u11ab|[\u11ae-\u11af]|[\u11b7-\u11b8]|\u11ba|[\u11bc-\u11c2]|\u11eb|"
+ "\u11f0|\u11f9|[\u1e00-\u1e9b]|[\u1ea0-\u1ef9]|[\u1f00-\u1f15]|"
+ "[\u1f18-\u1f1d]|[\u1f20-\u1f45]|[\u1f48-\u1f4d]|[\u1f50-\u1f57]|\u1f59|"
+ "\u1f5b|\u1f5d|[\u1f5f-\u1f7d]|[\u1f80-\u1fb4]|[\u1fb6-\u1fbc]|\u1fbe|"
+ "[\u1fc2-\u1fc4]|[\u1fc6-\u1fcc]|[\u1fd0-\u1fd3]|[\u1fd6-\u1fdb]|"
+ "[\u1fe0-\u1fec]|[\u1ff2-\u1ff4]|[\u1ff6-\u1ffc]|\u2126|[\u212a-\u212b]|"
+ "\u212e|[\u2180-\u2182]|[\u3041-\u3094]|[\u30a1-\u30fa]|[\u3105-\u312c]|"
+ "[\uac00-\ud7a3]",
+ flags=re.UNICODE,
+)
+
+
+RE_Ideographic = re.compile("[\u4e00-\u9fa5]|\u3007|[\u3021-\u3029]", flags=re.UNICODE)
+
+RE_CombiningChar = re.compile(
+ "[\u0300-\u0345]|[\u0360-\u0361]|[\u0483-\u0486]|[\u0591-\u05a1]|"
+ "[\u05a3-\u05b9]|[\u05bb-\u05bd]|\u05bf|[\u05c1-\u05c2]|\u05c4|"
+ "[\u064b-\u0652]|\u0670|[\u06d6-\u06dc]|[\u06dd-\u06df]|[\u06e0-\u06e4]|"
+ "[\u06e7-\u06e8]|[\u06ea-\u06ed]|[\u0901-\u0903]|\u093c|[\u093e-\u094c]|"
+ "\u094d|[\u0951-\u0954]|[\u0962-\u0963]|[\u0981-\u0983]|\u09bc|\u09be|"
+ "\u09bf|[\u09c0-\u09c4]|[\u09c7-\u09c8]|[\u09cb-\u09cd]|\u09d7|"
+ "[\u09e2-\u09e3]|\u0a02|\u0a3c|\u0a3e|\u0a3f|[\u0a40-\u0a42]|"
+ "[\u0a47-\u0a48]|[\u0a4b-\u0a4d]|[\u0a70-\u0a71]|[\u0a81-\u0a83]|\u0abc|"
+ "[\u0abe-\u0ac5]|[\u0ac7-\u0ac9]|[\u0acb-\u0acd]|[\u0b01-\u0b03]|\u0b3c|"
+ "[\u0b3e-\u0b43]|[\u0b47-\u0b48]|[\u0b4b-\u0b4d]|[\u0b56-\u0b57]|"
+ "[\u0b82-\u0b83]|[\u0bbe-\u0bc2]|[\u0bc6-\u0bc8]|[\u0bca-\u0bcd]|\u0bd7|"
+ "[\u0c01-\u0c03]|[\u0c3e-\u0c44]|[\u0c46-\u0c48]|[\u0c4a-\u0c4d]|"
+ "[\u0c55-\u0c56]|[\u0c82-\u0c83]|[\u0cbe-\u0cc4]|[\u0cc6-\u0cc8]|"
+ "[\u0cca-\u0ccd]|[\u0cd5-\u0cd6]|[\u0d02-\u0d03]|[\u0d3e-\u0d43]|"
+ "[\u0d46-\u0d48]|[\u0d4a-\u0d4d]|\u0d57|\u0e31|[\u0e34-\u0e3a]|"
+ "[\u0e47-\u0e4e]|\u0eb1|[\u0eb4-\u0eb9]|[\u0ebb-\u0ebc]|[\u0ec8-\u0ecd]|"
+ "[\u0f18-\u0f19]|\u0f35|\u0f37|\u0f39|\u0f3e|\u0f3f|[\u0f71-\u0f84]|"
+ "[\u0f86-\u0f8b]|[\u0f90-\u0f95]|\u0f97|[\u0f99-\u0fad]|[\u0fb1-\u0fb7]|"
+ "\u0fb9|[\u20d0-\u20dc]|\u20e1|[\u302a-\u302f]|\u3099|\u309a",
+ flags=re.UNICODE,
+)
RE_Digit = re.compile(
- u"[\u0030-\u0039]|[\u0660-\u0669]|[\u06F0-\u06F9]|[\u0966-\u096F]|"
- u"[\u09E6-\u09EF]|[\u0A66-\u0A6F]|[\u0AE6-\u0AEF]|[\u0B66-\u0B6F]|"
- u"[\u0BE7-\u0BEF]|[\u0C66-\u0C6F]|[\u0CE6-\u0CEF]|[\u0D66-\u0D6F]|"
- u"[\u0E50-\u0E59]|[\u0ED0-\u0ED9]|[\u0F20-\u0F29]", flags=re.UNICODE)
+ "[\u0030-\u0039]|[\u0660-\u0669]|[\u06f0-\u06f9]|[\u0966-\u096f]|"
+ "[\u09e6-\u09ef]|[\u0a66-\u0a6f]|[\u0ae6-\u0aef]|[\u0b66-\u0b6f]|"
+ "[\u0be7-\u0bef]|[\u0c66-\u0c6f]|[\u0ce6-\u0cef]|[\u0d66-\u0d6f]|"
+ "[\u0e50-\u0e59]|[\u0ed0-\u0ed9]|[\u0f20-\u0f29]",
+ flags=re.UNICODE,
+)
RE_Extender = re.compile(
- u"\u00B7|\u02D0|\u02D1|\u0387|\u0640|\u0E46|\u0EC6|\u3005|[\u3031-\u3035]|"
- u"[\u309D-\u309E]|[\u30FC-\u30FE]", flags=re.UNICODE)
-
-
-RE_Letter = re.compile(u'|'.join((RE_BaseChar.pattern, RE_Ideographic.pattern)),
- flags=re.UNICODE)
-
-
-RE_NameChar = re.compile(u'|'.join((
- RE_Letter.pattern, RE_Digit.pattern, '.', '-', '_', ':',
- RE_CombiningChar.pattern, RE_Extender.pattern,
- )), flags=re.UNICODE)
-
-
-RE_NCNameChar = re.compile(u'|'.join((
- RE_Letter.pattern, RE_Digit.pattern, '.', '-', '_', # <= no column
- RE_CombiningChar.pattern, RE_Extender.pattern,
- )), flags=re.UNICODE)
+ "\u00b7|\u02d0|\u02d1|\u0387|\u0640|\u0e46|\u0ec6|\u3005|[\u3031-\u3035]|"
+ "[\u309d-\u309e]|[\u30fc-\u30fe]",
+ flags=re.UNICODE,
+)
+
+
+RE_Letter = re.compile(
+ "|".join((RE_BaseChar.pattern, RE_Ideographic.pattern)), flags=re.UNICODE
+)
+
+
+RE_NameChar = re.compile(
+ "|".join(
+ (
+ RE_Letter.pattern,
+ RE_Digit.pattern,
+ ".",
+ "-",
+ "_",
+ ":",
+ RE_CombiningChar.pattern,
+ RE_Extender.pattern,
+ )
+ ),
+ flags=re.UNICODE,
+)
+
+
+RE_NCNameChar = re.compile(
+ "|".join(
+ (
+ RE_Letter.pattern,
+ RE_Digit.pattern,
+ ".",
+ "-",
+ "_", # <= no column
+ RE_CombiningChar.pattern,
+ RE_Extender.pattern,
+ )
+ ),
+ flags=re.UNICODE,
+)
class NormalizedString(Unicode):
- __type_name__ = 'normalizedString'
+ __type_name__ = "normalizedString"
__extends__ = Unicode
class Attributes(Unicode.Attributes):
@@ -131,26 +157,28 @@ class Attributes(Unicode.Attributes):
class Token(NormalizedString):
- __type_name__ = 'token'
+ __type_name__ = "token"
class Attributes(Unicode.Attributes):
white_space = "collapse"
+
# https://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Name
class Name(Token):
- __type_name__ = 'Name'
+ __type_name__ = "Name"
class Attributes(Unicode.Attributes):
# https://www.w3.org/TR/2000/WD-xml-2e-20000814#NT-Name
- pattern = '(%s)(%s)*' % (
- u'|'.join((RE_Letter.pattern, '_', ':')),
- RE_NameChar.pattern
+ pattern = "(%s)(%s)*" % (
+ "|".join((RE_Letter.pattern, "_", ":")),
+ RE_NameChar.pattern,
)
# https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName
class NCName(Name):
- __type_name__ = 'NCName'
+ __type_name__ = "NCName"
+
class Attributes(Unicode.Attributes):
pattern = "(%s|_)%s*" % (RE_Letter.pattern, RE_NCNameChar.pattern)
@@ -171,6 +199,7 @@ class Attributes(Unicode.Attributes):
QName = (NCName:)?NCName
"""
+
pattern = "(%s:)?(%s)" % (
NCName.Attributes.pattern,
NCName.Attributes.pattern,
@@ -178,18 +207,18 @@ class Attributes(Unicode.Attributes):
class NMToken(Unicode):
- __type_name__ = 'NMTOKEN'
+ __type_name__ = "NMTOKEN"
class Attributes(Unicode.Attributes):
unicode_pattern = PATT_NMTOKEN
class ID(NCName):
- __type_name__ = 'ID'
+ __type_name__ = "ID"
class Language(Token):
- __type_name__ = 'language'
+ __type_name__ = "language"
class Attributes(Unicode.Attributes):
- pattern = '[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*'
+ pattern = "[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*"
diff --git a/spyne/model/relational.py b/spyne/model/relational.py
index 4f2ab6773..cedd1655a 100644
--- a/spyne/model/relational.py
+++ b/spyne/model/relational.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -23,9 +22,9 @@
class FileData(ComplexModel):
_type_info = [
- ('name', Unicode),
- ('type', Unicode),
- ('path', Unicode),
+ ("name", Unicode),
+ ("type", Unicode),
+ ("path", Unicode),
]
@property
@@ -43,4 +42,3 @@ def handle(self):
@handle.setter
def handle(self, handle):
self._handle = handle
-
diff --git a/spyne/protocol/__init__.py b/spyne/protocol/__init__.py
index a98a9b610..0209b815f 100644
--- a/spyne/protocol/__init__.py
+++ b/spyne/protocol/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -28,17 +27,34 @@
class ProtocolBase(InProtocolBase, OutProtocolBase):
- def __init__(self, app=None, validator=None, mime_type=None,
- ignore_uncap=False, ignore_wrappers=False, binary_encoding=None,
- string_encoding='utf8'):
-
- InProtocolBase.__init__(self, app=app, validator=validator,
- mime_type=mime_type, ignore_wrappers=ignore_wrappers,
- binary_encoding=binary_encoding)
-
- OutProtocolBase.__init__(self, app=app, mime_type=mime_type,
- ignore_wrappers=ignore_wrappers, ignore_uncap=ignore_uncap,
- binary_encoding=binary_encoding)
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ mime_type=None,
+ ignore_uncap=False,
+ ignore_wrappers=False,
+ binary_encoding=None,
+ string_encoding="utf8",
+ ):
+
+ InProtocolBase.__init__(
+ self,
+ app=app,
+ validator=validator,
+ mime_type=mime_type,
+ ignore_wrappers=ignore_wrappers,
+ binary_encoding=binary_encoding,
+ )
+
+ OutProtocolBase.__init__(
+ self,
+ app=app,
+ mime_type=mime_type,
+ ignore_wrappers=ignore_wrappers,
+ ignore_uncap=ignore_uncap,
+ binary_encoding=binary_encoding,
+ )
self.default_string_encoding = string_encoding
self.ignore_empty_faultactor = True
diff --git a/spyne/protocol/_base.py b/spyne/protocol/_base.py
index 6c4f6c447..c29419fef 100644
--- a/spyne/protocol/_base.py
+++ b/spyne/protocol/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -20,24 +19,24 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
from datetime import datetime
from weakref import WeakKeyDictionary
-from spyne import ProtocolContext, EventManager
from spyne.const import DEFAULT_LOCALE
-from spyne.model import Array
+from spyne.context import ProtocolContext
from spyne.error import ResourceNotFoundError
+from spyne.evmgr import EventManager
+from spyne.model import Array
from spyne.util import DefaultAttrDict
-from spyne.util.six import string_types
-
_MISSING = type("_MISSING", (object,), {})()
class ProtocolMixin(object):
- mime_type = 'application/octet-stream'
+ mime_type = "application/octet-stream"
SOFT_VALIDATION = type("Soft", (object,), {})
REQUEST = type("Request", (object,), {})
@@ -55,8 +54,14 @@ class ProtocolMixin(object):
type_attrs = {}
"""Default customizations to be passed to underlying classes."""
- def __init__(self, app=None, mime_type=None, ignore_wrappers=None,
- binary_encoding=None, string_encoding=None):
+ def __init__(
+ self,
+ app=None,
+ mime_type=None,
+ ignore_wrappers=None,
+ binary_encoding=None,
+ string_encoding=None,
+ ):
self.__app = None
self.set_app(app)
@@ -158,31 +163,34 @@ def app(self):
@staticmethod
def strip_wrappers(cls, inst):
- ti = getattr(cls, '_type_info', {})
+ ti = getattr(cls, "_type_info", {})
while len(ti) == 1 and cls.Attributes._wrapper:
# Wrappers are auto-generated objects that have exactly one
# child type.
- key, = ti.keys()
+ (key,) = ti.keys()
if not issubclass(cls, Array):
inst = getattr(inst, key, None)
- cls, = ti.values()
- ti = getattr(cls, '_type_info', {})
+ (cls,) = ti.values()
+ ti = getattr(cls, "_type_info", {})
return cls, inst
def set_app(self, value):
- assert self.__app is None, "One protocol instance should belong to one " \
- "application instance. It currently belongs " \
- "to: %r" % self.__app
+ assert self.__app is None, (
+ "One protocol instance should belong to one "
+ "application instance. It currently belongs "
+ "to: %r" % self.__app
+ )
self.__app = value
@staticmethod
def issubclass(sub, cls):
- suborig = getattr(sub, '__orig__', None)
- clsorig = getattr(cls, '__orig__', None)
- return issubclass(sub if suborig is None else suborig,
- cls if clsorig is None else clsorig)
+ suborig = getattr(sub, "__orig__", None)
+ clsorig = getattr(cls, "__orig__", None)
+ return issubclass(
+ sub if suborig is None else suborig, cls if clsorig is None else clsorig
+ )
def get_cls_attrs(self, cls):
logger.debug("%r attrcache size: %d", self, len(self._attrcache))
@@ -190,10 +198,13 @@ def get_cls_attrs(self, cls):
if attr is not None:
return attr
- self._attrcache[cls] = attr = DefaultAttrDict([
+ self._attrcache[cls] = attr = DefaultAttrDict(
+ [
(k, getattr(cls.Attributes, k))
- for k in dir(cls.Attributes) + META_ATTR
- if not k.startswith('__')])
+ for k in dir(cls.Attributes) + META_ATTR
+ if not k.startswith("__")
+ ]
+ )
if cls.Attributes.prot_attrs:
cls_attrs = cls.Attributes.prot_attrs.get(self.__class__, {})
@@ -240,8 +251,8 @@ def get_call_handles(self, ctx):
"""
name = ctx.method_request_string
- if not name.startswith(u"{"):
- name = u'{%s}%s' % (self.app.interface.get_tns(), name)
+ if not name.startswith("{"):
+ name = "{%s}%s" % (self.app.interface.get_tns(), name)
call_handles = self.app.interface.service_method_map.get(name, [])
@@ -259,26 +270,35 @@ def get_polymorphic_target(self, cls, inst):
orig_cls = cls.__orig__ or cls
if inst.__class__ is orig_cls:
- logger.debug("PMORPH Skipped: Instance class %r is the same as "
- "designated base class", inst.__class__)
+ logger.debug(
+ "PMORPH Skipped: Instance class %r is the same as "
+ "designated base class",
+ inst.__class__,
+ )
return cls, False
if not isinstance(inst, orig_cls):
- logger.debug("PMORPH Skipped: Instance class %r is not a subclass "
- "of designated base class %r", inst.__class__, orig_cls)
+ logger.debug(
+ "PMORPH Skipped: Instance class %r is not a subclass "
+ "of designated base class %r",
+ inst.__class__,
+ orig_cls,
+ )
return cls, False
cls_attr = self.get_cls_attrs(cls)
polymap_cls = cls_attr.polymap.get(inst.__class__, None)
if polymap_cls is not None:
- logger.debug("PMORPH OK: cls switch with polymap: %r => %r",
- cls, polymap_cls)
+ logger.debug(
+ "PMORPH OK: cls switch with polymap: %r => %r", cls, polymap_cls
+ )
return polymap_cls, True
else:
- logger.debug("PMORPH OK: cls switch without polymap: %r => %r",
- cls, inst.__class__)
+ logger.debug(
+ "PMORPH OK: cls switch without polymap: %r => %r", cls, inst.__class__
+ )
return inst.__class__, True
@staticmethod
@@ -309,8 +329,7 @@ def trc_verbose(cls, locale, default):
else:
_log_tr = "translated to '%s' with"
- logger.debug(' '.join(("%r ", _log_tr, _log_locale)),
- cls, retval, locale)
+ logger.debug(" ".join(("%r ", _log_tr, _log_locale)), cls, retval, locale)
return retval
@@ -350,7 +369,7 @@ def trd_verbose(trdict, locale, default):
retval = default
_log_tr = "translated to '%s' without any translations at all with"
- elif isinstance(trdict, string_types):
+ elif isinstance(trdict, str):
retval = trdict
_log_tr = "translated to '%s' regardless of"
@@ -362,8 +381,7 @@ def trd_verbose(trdict, locale, default):
else:
_log_tr = "translated to '%s' with"
- logger.debug(' '.join(("%r ", _log_tr, _log_locale)),
- trdict, retval, locale)
+ logger.debug(" ".join(("%r ", _log_tr, _log_locale)), trdict, retval, locale)
return retval
@@ -381,7 +399,7 @@ def trd(trdict, locale, default):
locale = DEFAULT_LOCALE
if trdict is None:
return default
- if isinstance(trdict, string_types):
+ if isinstance(trdict, str):
return trdict
return trdict.get(locale, default)
@@ -415,4 +433,4 @@ def sort_fields(self, cls=None, items=None):
return items
-META_ATTR = ['nullable', 'default_factory']
+META_ATTR = ["nullable", "default_factory"]
diff --git a/spyne/protocol/_inbase.py b/spyne/protocol/_inbase.py
index a2b2ff267..607b49187 100644
--- a/spyne/protocol/_inbase.py
+++ b/spyne/protocol/_inbase.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -20,54 +19,68 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
import re
-import pytz
import uuid
-
+from datetime import date, datetime, time, timedelta
+from decimal import Decimal as D
+from decimal import InvalidOperation
from math import modf
-from time import strptime, mktime
-from datetime import timedelta, time, datetime, date
-from decimal import Decimal as D, InvalidOperation
+from time import mktime, strptime
+import pytz
from pytz import FixedOffset
try:
- from lxml import etree
- from lxml import html
+ from lxml import etree, html
except ImportError:
etree = None
html = None
-from spyne.protocol._base import ProtocolMixin
-from spyne.model import ModelBase, XmlAttribute, Array, Null, \
- ByteArray, File, ComplexModelBase, AnyXml, AnyHtml, Unicode, String, \
- Decimal, Double, Integer, Time, DateTime, Uuid, Date, Duration, Boolean, Any
-
from spyne.error import ValidationError
-
-from spyne.model.binary import binary_decoding_handlers, BINARY_ENCODING_USE_DEFAULT
-
-from spyne.util import six
+from spyne.model import (
+ Any,
+ AnyHtml,
+ AnyXml,
+ Array,
+ Boolean,
+ ByteArray,
+ ComplexModelBase,
+ Date,
+ DateTime,
+ Decimal,
+ Double,
+ Duration,
+ File,
+ Integer,
+ ModelBase,
+ Null,
+ String,
+ Time,
+ Unicode,
+ Uuid,
+ XmlAttribute,
+)
+from spyne.model.binary import BINARY_ENCODING_USE_DEFAULT, binary_decoding_handlers
from spyne.model.enum import EnumBase
-from spyne.model.primitive.datetime import TIME_PATTERN, DATE_PATTERN
-
+from spyne.model.primitive.datetime import DATE_PATTERN, TIME_PATTERN
+from spyne.protocol._base import ProtocolMixin
from spyne.util.cdict import cdict
-
_date_re = re.compile(DATE_PATTERN)
_time_re = re.compile(TIME_PATTERN)
_duration_re = re.compile(
- r'(?P-?)'
- r'P'
- r'(?:(?P\d+)Y)?'
- r'(?:(?P\d+)M)?'
- r'(?:(?P\d+)D)?'
- r'(?:T(?:(?P\d+)H)?'
- r'(?:(?P\d+)M)?'
- r'(?:(?P\d+(.\d+)?)S)?)?'
- )
+ r"(?P-?)"
+ r"P"
+ r"(?:(?P\d+)Y)?"
+ r"(?:(?P\d+)M)?"
+ r"(?:(?P\d+)D)?"
+ r"(?:T(?:(?P\d+)H)?"
+ r"(?:(?P\d+)M)?"
+ r"(?:(?P\d+(.\d+)?)S)?)?"
+)
class InProtocolBase(ProtocolMixin):
@@ -96,14 +109,25 @@ class InProtocolBase(ProtocolMixin):
default instead of subclassing the releavant protocol implementation.
"""
- def __init__(self, app=None, validator=None, mime_type=None,
- ignore_wrappers=False, binary_encoding=None, string_encoding=None):
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ mime_type=None,
+ ignore_wrappers=False,
+ binary_encoding=None,
+ string_encoding=None,
+ ):
self.validator = None
- super(InProtocolBase, self).__init__(app=app, mime_type=mime_type,
+ super(InProtocolBase, self).__init__(
+ app=app,
+ mime_type=mime_type,
ignore_wrappers=ignore_wrappers,
- binary_encoding=binary_encoding, string_encoding=string_encoding)
+ binary_encoding=binary_encoding,
+ string_encoding=string_encoding,
+ )
self.message = None
self.validator = None
@@ -128,7 +152,7 @@ def __init__(self, app=None, validator=None, mime_type=None,
EnumBase: self.enum_base_from_bytes,
ModelBase: self.model_base_from_bytes,
XmlAttribute: self.xmlattribute_from_bytes,
- ComplexModelBase: self.complex_model_base_from_bytes
+ ComplexModelBase: self.complex_model_base_from_bytes,
}
self._from_bytes_handlers = cdict(fsh)
@@ -148,14 +172,13 @@ def __init__(self, app=None, validator=None, mime_type=None,
self._from_unicode_handlers[DateTime] = self.datetime_from_unicode
self._from_unicode_handlers[Duration] = self.duration_from_unicode
-
self._datetime_dsmap = {
None: self._datetime_from_unicode,
- 'sec': self._datetime_from_sec,
- 'sec_float': self._datetime_from_sec_float,
- 'msec': self._datetime_from_msec,
- 'msec_float': self._datetime_from_msec_float,
- 'usec': self._datetime_from_usec,
+ "sec": self._datetime_from_sec,
+ "sec_float": self._datetime_from_sec_float,
+ "msec": self._datetime_from_msec,
+ "msec_float": self._datetime_from_msec_float,
+ "usec": self._datetime_from_usec,
}
def _datetime_from_sec(self, cls, value):
@@ -227,8 +250,11 @@ def from_bytes(self, class_, string, *args, **kwargs):
if string is None:
return None
- if isinstance(string, six.string_types) and \
- len(string) == 0 and class_.Attributes.empty_is_none:
+ if (
+ isinstance(string, str)
+ and len(string) == 0
+ and class_.Attributes.empty_is_none
+ ):
return None
handler = self._from_bytes_handlers[class_]
@@ -238,15 +264,9 @@ def from_unicode(self, class_, string, *args, **kwargs):
if string is None:
return None
- #if not six.PY2:
- # assert isinstance(string, str), \
- # "Invalid type passed to `from_unicode`: {}".format(
- # (class_, type(string), string))
-
cls_attrs = self.get_cls_attrs(class_)
- if isinstance(string, six.string_types) and len(string) == 0 and \
- cls_attrs.empty_is_none:
+ if isinstance(string, str) and len(string) == 0 and cls_attrs.empty_is_none:
return None
handler = self._from_unicode_handlers[class_]
@@ -283,8 +303,8 @@ def uuid_from_unicode(self, cls, string, suggested_encoding=None):
retval = string
- if ser_as in ('bytes', 'bytes_le'):
- retval, = binary_decoding_handlers[encoding](string)
+ if ser_as in ("bytes", "bytes_le"):
+ (retval,) = binary_decoding_handlers[encoding](string)
try:
retval = _uuid_deserialize[ser_as](retval)
@@ -303,10 +323,10 @@ def uuid_from_bytes(self, cls, string, suggested_encoding=None, **_):
retval = string
- if ser_as in ('bytes', 'bytes_le'):
- retval, = binary_decoding_handlers[encoding](string)
- elif isinstance(string, six.binary_type):
- retval = string.decode('ascii')
+ if ser_as in ("bytes", "bytes_le"):
+ (retval,) = binary_decoding_handlers[encoding](string)
+ elif isinstance(string, bytes):
+ retval = string.decode("ascii")
try:
retval = _uuid_deserialize[ser_as](retval)
@@ -318,29 +338,31 @@ def uuid_from_bytes(self, cls, string, suggested_encoding=None, **_):
def unicode_from_bytes(self, cls, value):
retval = value
- if isinstance(value, six.binary_type):
+ if isinstance(value, bytes):
cls_attrs = self.get_cls_attrs(cls)
if cls_attrs.encoding is not None:
- retval = six.text_type(value, cls_attrs.encoding,
- errors=cls_attrs.unicode_errors)
+ retval = str(value, cls_attrs.encoding, errors=cls_attrs.unicode_errors)
elif self.string_encoding is not None:
- retval = six.text_type(value, self.string_encoding,
- errors=cls_attrs.unicode_errors)
+ retval = str(
+ value, self.string_encoding, errors=cls_attrs.unicode_errors
+ )
else:
- retval = six.text_type(value, errors=cls_attrs.unicode_errors)
+ retval = str(value, errors=cls_attrs.unicode_errors)
return retval
def string_from_bytes(self, cls, value):
retval = value
cls_attrs = self.get_cls_attrs(cls)
- if isinstance(value, six.text_type):
+ if isinstance(value, str):
if cls_attrs.encoding is None:
- raise Exception("You need to define a source encoding for "
- "decoding incoming unicode values.")
+ raise Exception(
+ "You need to define a source encoding for "
+ "decoding incoming unicode values."
+ )
else:
retval = value.encode(cls_attrs.encoding)
@@ -348,10 +370,11 @@ def string_from_bytes(self, cls, value):
def decimal_from_unicode(self, cls, string):
cls_attrs = self.get_cls_attrs(cls)
- if cls_attrs.max_str_len is not None and len(string) > \
- cls_attrs.max_str_len:
- raise ValidationError(string, "Decimal %%r longer than %d "
- "characters" % cls_attrs.max_str_len)
+ if cls_attrs.max_str_len is not None and len(string) > cls_attrs.max_str_len:
+ raise ValidationError(
+ string,
+ "Decimal %%r longer than %d " "characters" % cls_attrs.max_str_len,
+ )
try:
return D(string)
@@ -359,8 +382,9 @@ def decimal_from_unicode(self, cls, string):
raise ValidationError(string, "%%r: %r" % e)
def decimal_from_bytes(self, cls, string):
- return self.decimal_from_unicode(cls,
- string.decode(self.default_string_encoding))
+ return self.decimal_from_unicode(
+ cls, string.decode(self.default_string_encoding)
+ )
def double_from_bytes(self, cls, string):
try:
@@ -371,12 +395,14 @@ def double_from_bytes(self, cls, string):
def integer_from_bytes(self, cls, string):
cls_attrs = self.get_cls_attrs(cls)
- if isinstance(string, (six.text_type, six.binary_type)) and \
- cls_attrs.max_str_len is not None and \
- len(string) > cls_attrs.max_str_len:
- raise ValidationError(string,
- "Integer %%r longer than %d characters"
- % cls_attrs.max_str_len)
+ if (
+ isinstance(string, (str, bytes))
+ and cls_attrs.max_str_len is not None
+ and len(string) > cls_attrs.max_str_len
+ ):
+ raise ValidationError(
+ string, "Integer %%r longer than %d characters" % cls_attrs.max_str_len
+ )
try:
return int(string)
@@ -388,21 +414,21 @@ def time_from_unicode(self, cls, string):
match = _time_re.match(string)
if match is None:
- raise ValidationError(string, "%%r does not match regex %r " %
- _time_re.pattern)
+ raise ValidationError(
+ string, "%%r does not match regex %r " % _time_re.pattern
+ )
fields = match.groupdict(0)
- microsec = fields.get('sec_frac')
+ microsec = fields.get("sec_frac")
if microsec is None or microsec == 0:
microsec = 0
else:
microsec = min(999999, int(round(float(microsec) * 1e6)))
- return time(int(fields['hr']), int(fields['min']),
- int(fields['sec']), microsec)
+ return time(int(fields["hr"]), int(fields["min"]), int(fields["sec"]), microsec)
def time_from_bytes(self, cls, string):
- if isinstance(string, six.binary_type):
+ if isinstance(string, bytes):
string = string.decode(self.default_string_encoding)
return self.time_from_unicode(cls, string)
@@ -413,15 +439,15 @@ def date_from_unicode_iso(self, cls, string):
"""
try:
- return date(*(strptime(string, u'%Y-%m-%d')[0:3]))
+ return date(*(strptime(string, "%Y-%m-%d")[0:3]))
except ValueError:
match = cls._offset_re.match(string)
if match:
- year = int(match.group('year'))
- month = int(match.group('month'))
- day = int(match.group('day'))
+ year = int(match.group("year"))
+ month = int(match.group("month"))
+ day = int(match.group("day"))
return date(year, month, day)
@@ -429,7 +455,8 @@ def date_from_unicode_iso(self, cls, string):
def enum_base_from_bytes(self, cls, value):
if self.validator is self.SOFT_VALIDATION and not (
- cls.validate_string(cls, value)):
+ cls.validate_string(cls, value)
+ ):
raise ValidationError(value)
return getattr(cls, value)
@@ -450,8 +477,7 @@ def datetime_from_unicode_iso(self, cls, string):
if match is None:
match = cls._offset_re.match(string)
if match:
- tz_hr, tz_min = [int(match.group(x))
- for x in ("tz_hr", "tz_min")]
+ tz_hr, tz_min = [int(match.group(x)) for x in ("tz_hr", "tz_min")]
tz = FixedOffset(tz_hr * 60 + tz_min, {})
retval = _parse_datetime_iso_match(match, tz=tz)
if astz is not None:
@@ -473,14 +499,14 @@ def datetime_from_unicode(self, cls, string):
return self._datetime_dsmap[serialize_as](cls, string)
def datetime_from_bytes(self, cls, string):
- if isinstance(string, six.binary_type):
+ if isinstance(string, bytes):
string = string.decode(self.default_string_encoding)
serialize_as = self.get_cls_attrs(cls).serialize_as
return self._datetime_dsmap[serialize_as](cls, string)
def date_from_bytes(self, cls, string):
- if isinstance(string, six.binary_type):
+ if isinstance(string, bytes):
string = string.decode(self.default_string_encoding)
date_format = self._get_date_format(self.get_cls_attrs(cls))
@@ -494,11 +520,13 @@ def date_from_bytes(self, cls, string):
except ValueError as e:
match = cls._offset_re.match(string)
if match:
- return date(int(match.group('year')),
- int(match.group('month')), int(match.group('day')))
+ return date(
+ int(match.group("year")),
+ int(match.group("month")),
+ int(match.group("day")),
+ )
else:
- raise ValidationError(string,
- "%%r: %s" % repr(e).replace("%", "%%"))
+ raise ValidationError(string, "%%r: %s" % repr(e).replace("%", "%%"))
def date_from_unicode(self, cls, string):
date_format = self._get_date_format(self.get_cls_attrs(cls))
@@ -512,8 +540,11 @@ def date_from_unicode(self, cls, string):
except ValueError as e:
match = cls._offset_re.match(string)
if match:
- return date(int(match.group('year')),
- int(match.group('month')), int(match.group('day')))
+ return date(
+ int(match.group("year")),
+ int(match.group("month")),
+ int(match.group("day")),
+ )
else:
# the message from ValueError is quite nice already
raise ValidationError(e.message, "%s")
@@ -521,36 +552,42 @@ def date_from_unicode(self, cls, string):
def duration_from_unicode(self, cls, string):
duration = _duration_re.match(string).groupdict(0)
if duration is None:
- raise ValidationError(string,
- "Time data '%%s' does not match regex '%s'" %
- (_duration_re.pattern,))
-
- days = int(duration['days'])
- days += int(duration['months']) * 30
- days += int(duration['years']) * 365
- hours = int(duration['hours'])
- minutes = int(duration['minutes'])
- seconds = float(duration['seconds'])
+ raise ValidationError(
+ string,
+ "Time data '%%s' does not match regex '%s'" % (_duration_re.pattern,),
+ )
+
+ days = int(duration["days"])
+ days += int(duration["months"]) * 30
+ days += int(duration["years"]) * 365
+ hours = int(duration["hours"])
+ minutes = int(duration["minutes"])
+ seconds = float(duration["seconds"])
f, i = modf(seconds)
seconds = i
microseconds = int(1e6 * f)
- delta = timedelta(days=days, hours=hours, minutes=minutes,
- seconds=seconds, microseconds=microseconds)
+ delta = timedelta(
+ days=days,
+ hours=hours,
+ minutes=minutes,
+ seconds=seconds,
+ microseconds=microseconds,
+ )
- if duration['sign'] == "-":
+ if duration["sign"] == "-":
delta *= -1
return delta
def duration_from_bytes(self, cls, string):
- if isinstance(string, six.binary_type):
+ if isinstance(string, bytes):
string = string.decode(self.default_string_encoding)
return self.duration_from_unicode(cls, string)
def boolean_from_bytes(self, cls, string):
- return string.lower() in ('true', '1')
+ return string.lower() in ("true", "1")
def byte_array_from_bytes(self, cls, value, suggested_encoding=None):
encoding = self.get_cls_attrs(cls).encoding
@@ -569,12 +606,12 @@ def complex_model_base_from_bytes(self, cls, string, **_):
raise TypeError("Only primitives can be deserialized from string.")
def array_from_bytes(self, cls, string, **_):
- if self.get_cls_attrs(cls).serialize_as != 'sd-list':
+ if self.get_cls_attrs(cls).serialize_as != "sd-list":
raise TypeError("Only primitives can be deserialized from string.")
# sd-list being space-delimited list.
retval = []
- inner_type, = cls._type_info.values()
+ (inner_type,) = cls._type_info.values()
for s in string.split():
retval.append(self.from_bytes(inner_type, s))
@@ -603,14 +640,6 @@ def _datetime_from_unicode(self, cls, string):
retval = parser(self, cls, string)
elif dt_format is not None:
- if six.PY2:
- # FIXME: perhaps it should encode to string's encoding instead
- # of utf8 all the time
- if isinstance(dt_format, six.text_type):
- dt_format = dt_format.encode('utf8')
- if isinstance(string, six.text_type):
- string = string.encode('utf8')
-
retval = datetime.strptime(string, dt_format)
astz = cls_attrs.as_timezone
@@ -624,31 +653,27 @@ def _datetime_from_unicode(self, cls, string):
_uuid_deserialize = {
- None: lambda s: uuid.UUID(s.decode('ascii') if isinstance(s, bytes) else s),
- 'hex': lambda s: uuid.UUID(hex=s),
- 'urn': lambda s: uuid.UUID(hex=s),
- 'bytes': lambda s: uuid.UUID(bytes=s),
- 'bytes_le': lambda s: uuid.UUID(bytes_le=s),
- 'fields': lambda s: uuid.UUID(fields=s),
- 'int': lambda s: uuid.UUID(int=s),
- ('int', int): lambda s: uuid.UUID(int=s),
- ('int', str): lambda s: uuid.UUID(int=int(s)),
+ None: lambda s: uuid.UUID(s.decode("ascii") if isinstance(s, bytes) else s),
+ "hex": lambda s: uuid.UUID(hex=s),
+ "urn": lambda s: uuid.UUID(hex=s),
+ "bytes": lambda s: uuid.UUID(bytes=s),
+ "bytes_le": lambda s: uuid.UUID(bytes_le=s),
+ "fields": lambda s: uuid.UUID(fields=s),
+ "int": lambda s: uuid.UUID(int=s),
+ ("int", int): lambda s: uuid.UUID(int=s),
+ ("int", str): lambda s: uuid.UUID(int=int(s)),
}
-if six.PY2:
- _uuid_deserialize[None] = lambda s: uuid.UUID(s)
- _uuid_deserialize[('int', long)] = _uuid_deserialize[('int', int)]
-
def _parse_datetime_iso_match(date_match, tz=None):
fields = date_match.groupdict()
- year = int(fields.get('year'))
- month = int(fields.get('month'))
- day = int(fields.get('day'))
- hour = int(fields.get('hr'))
- minute = int(fields.get('min'))
- second = int(fields.get('sec'))
+ year = int(fields.get("year"))
+ month = int(fields.get("month"))
+ day = int(fields.get("day"))
+ hour = int(fields.get("hr"))
+ minute = int(fields.get("min"))
+ second = int(fields.get("sec"))
usecond = fields.get("sec_frac")
if usecond is None:
usecond = 0
@@ -660,50 +685,45 @@ def _parse_datetime_iso_match(date_match, tz=None):
return datetime(year, month, day, hour, minute, second, usecond, tz)
-_dt_sec = lambda cls, val: \
- int(mktime(val.timetuple()))
-_dt_sec_float = lambda cls, val: \
- mktime(val.timetuple()) + (val.microsecond / 1e6)
+_dt_sec = lambda cls, val: int(mktime(val.timetuple()))
+_dt_sec_float = lambda cls, val: mktime(val.timetuple()) + (val.microsecond / 1e6)
-_dt_msec = lambda cls, val: \
- int(mktime(val.timetuple())) * 1000 + (val.microsecond // 1000)
-_dt_msec_float = lambda cls, val: \
- mktime(val.timetuple()) * 1000 + (val.microsecond / 1000.0)
+_dt_msec = lambda cls, val: int(mktime(val.timetuple())) * 1000 + (
+ val.microsecond // 1000
+)
+_dt_msec_float = lambda cls, val: mktime(val.timetuple()) * 1000 + (
+ val.microsecond / 1000.0
+)
-_dt_usec = lambda cls, val: \
- int(mktime(val.timetuple())) * 1000000 + val.microsecond
+_dt_usec = lambda cls, val: int(mktime(val.timetuple())) * 1000000 + val.microsecond
_datetime_smap = {
- 'sec': _dt_sec,
- 'secs': _dt_sec,
- 'second': _dt_sec,
- 'seconds': _dt_sec,
-
- 'sec_float': _dt_sec_float,
- 'secs_float': _dt_sec_float,
- 'second_float': _dt_sec_float,
- 'seconds_float': _dt_sec_float,
-
- 'msec': _dt_msec,
- 'msecs': _dt_msec,
- 'msecond': _dt_msec,
- 'mseconds': _dt_msec,
- 'millisecond': _dt_msec,
- 'milliseconds': _dt_msec,
-
- 'msec_float': _dt_msec_float,
- 'msecs_float': _dt_msec_float,
- 'msecond_float': _dt_msec_float,
- 'mseconds_float': _dt_msec_float,
- 'millisecond_float': _dt_msec_float,
- 'milliseconds_float': _dt_msec_float,
-
- 'usec': _dt_usec,
- 'usecs': _dt_usec,
- 'usecond': _dt_usec,
- 'useconds': _dt_usec,
- 'microsecond': _dt_usec,
- 'microseconds': _dt_usec,
+ "sec": _dt_sec,
+ "secs": _dt_sec,
+ "second": _dt_sec,
+ "seconds": _dt_sec,
+ "sec_float": _dt_sec_float,
+ "secs_float": _dt_sec_float,
+ "second_float": _dt_sec_float,
+ "seconds_float": _dt_sec_float,
+ "msec": _dt_msec,
+ "msecs": _dt_msec,
+ "msecond": _dt_msec,
+ "mseconds": _dt_msec,
+ "millisecond": _dt_msec,
+ "milliseconds": _dt_msec,
+ "msec_float": _dt_msec_float,
+ "msecs_float": _dt_msec_float,
+ "msecond_float": _dt_msec_float,
+ "mseconds_float": _dt_msec_float,
+ "millisecond_float": _dt_msec_float,
+ "milliseconds_float": _dt_msec_float,
+ "usec": _dt_usec,
+ "usecs": _dt_usec,
+ "usecond": _dt_usec,
+ "useconds": _dt_usec,
+ "microsecond": _dt_usec,
+ "microseconds": _dt_usec,
}
diff --git a/spyne/protocol/_outbase.py b/spyne/protocol/_outbase.py
index e9c904eb6..fcb6fa274 100644
--- a/spyne/protocol/_outbase.py
+++ b/spyne/protocol/_outbase.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -20,41 +19,61 @@
from __future__ import print_function, unicode_literals
import logging
+
logger = logging.getLogger(__name__)
+import errno
import re
import uuid
-import errno
-
-from os.path import isabs, join, abspath
from collections import deque
from datetime import datetime
from decimal import Decimal as D
-from mmap import mmap, ACCESS_READ
+from mmap import ACCESS_READ, mmap
+from os.path import abspath, isabs, join
from time import mktime, strftime
try:
- from lxml import etree
- from lxml import html
+ from lxml import etree, html
except ImportError:
etree = None
html = None
-from spyne.protocol._base import ProtocolMixin
-from spyne.model import ModelBase, XmlAttribute, SimpleModel, Null, \
- ByteArray, File, ComplexModelBase, AnyXml, AnyHtml, Unicode, Decimal, \
- Double, Integer, Time, DateTime, Uuid, Duration, Boolean, AnyDict, \
- AnyUri, PushBase, Date
+from spyne.const.http import HTTP_400, HTTP_401, HTTP_404, HTTP_405, HTTP_413, HTTP_500
+from spyne.error import (
+ Fault,
+ InternalError,
+ InvalidCredentialsError,
+ RequestNotAllowed,
+ RequestTooLongError,
+ ResourceNotFoundError,
+)
+from spyne.model import (
+ AnyDict,
+ AnyHtml,
+ AnyUri,
+ AnyXml,
+ Boolean,
+ ByteArray,
+ ComplexModelBase,
+ Date,
+ DateTime,
+ Decimal,
+ Double,
+ Duration,
+ File,
+ Integer,
+ ModelBase,
+ Null,
+ PushBase,
+ SimpleModel,
+ Time,
+ Unicode,
+ Uuid,
+ XmlAttribute,
+)
+from spyne.model.binary import BINARY_ENCODING_USE_DEFAULT, binary_encoding_handlers
from spyne.model.relational import FileData
-
-from spyne.const.http import HTTP_400, HTTP_401, HTTP_404, HTTP_405, HTTP_413, \
- HTTP_500
-from spyne.error import Fault, InternalError, ResourceNotFoundError, \
- RequestTooLongError, RequestNotAllowed, InvalidCredentialsError
-from spyne.model.binary import binary_encoding_handlers, \
- BINARY_ENCODING_USE_DEFAULT
-
-from spyne.util import six
+from spyne.protocol._base import ProtocolMixin
from spyne.util.cdict import cdict
@@ -83,12 +102,23 @@ class OutProtocolBase(ProtocolMixin):
of serializing return values instead of raising a TypeError.
"""
- def __init__(self, app=None, mime_type=None, ignore_uncap=False,
- ignore_wrappers=False, binary_encoding=None, string_encoding=None):
-
- super(OutProtocolBase, self).__init__(app=app, mime_type=mime_type,
+ def __init__(
+ self,
+ app=None,
+ mime_type=None,
+ ignore_uncap=False,
+ ignore_wrappers=False,
+ binary_encoding=None,
+ string_encoding=None,
+ ):
+
+ super(OutProtocolBase, self).__init__(
+ app=app,
+ mime_type=mime_type,
ignore_wrappers=ignore_wrappers,
- binary_encoding=binary_encoding, string_encoding=string_encoding)
+ binary_encoding=binary_encoding,
+ string_encoding=string_encoding,
+ )
self.ignore_uncap = ignore_uncap
self.message = None
@@ -96,59 +126,64 @@ def __init__(self, app=None, mime_type=None, ignore_uncap=False,
if mime_type is not None:
self.mime_type = mime_type
- self._to_bytes_handlers = cdict({
- ModelBase: self.model_base_to_bytes,
- File: self.file_to_bytes,
- Time: self.time_to_bytes,
- Uuid: self.uuid_to_bytes,
- Null: self.null_to_bytes,
- Date: self.date_to_bytes,
- Double: self.double_to_bytes,
- AnyXml: self.any_xml_to_bytes,
- Unicode: self.unicode_to_bytes,
- Boolean: self.boolean_to_bytes,
- Decimal: self.decimal_to_bytes,
- Integer: self.integer_to_bytes,
- AnyHtml: self.any_html_to_bytes,
- DateTime: self.datetime_to_bytes,
- Duration: self.duration_to_bytes,
- ByteArray: self.byte_array_to_bytes,
- XmlAttribute: self.xmlattribute_to_bytes,
- ComplexModelBase: self.complex_model_base_to_bytes,
- })
-
- self._to_unicode_handlers = cdict({
- ModelBase: self.model_base_to_unicode,
- File: self.file_to_unicode,
- Time: self.time_to_unicode,
- Date: self.date_to_unicode,
- Uuid: self.uuid_to_unicode,
- Null: self.null_to_unicode,
- Double: self.double_to_unicode,
- AnyXml: self.any_xml_to_unicode,
- AnyUri: self.any_uri_to_unicode,
- AnyDict: self.any_dict_to_unicode,
- AnyHtml: self.any_html_to_unicode,
- Unicode: self.unicode_to_unicode,
- Boolean: self.boolean_to_unicode,
- Decimal: self.decimal_to_unicode,
- Integer: self.integer_to_unicode,
- # FIXME: Would we need a to_unicode for localized dates?
- DateTime: self.datetime_to_unicode,
- Duration: self.duration_to_unicode,
- ByteArray: self.byte_array_to_unicode,
- XmlAttribute: self.xmlattribute_to_unicode,
- ComplexModelBase: self.complex_model_base_to_unicode,
- })
-
- self._to_bytes_iterable_handlers = cdict({
- File: self.file_to_bytes_iterable,
- ByteArray: self.byte_array_to_bytes_iterable,
- ModelBase: self.model_base_to_bytes_iterable,
- SimpleModel: self.simple_model_to_bytes_iterable,
- ComplexModelBase: self.complex_model_to_bytes_iterable,
- })
-
+ self._to_bytes_handlers = cdict(
+ {
+ ModelBase: self.model_base_to_bytes,
+ File: self.file_to_bytes,
+ Time: self.time_to_bytes,
+ Uuid: self.uuid_to_bytes,
+ Null: self.null_to_bytes,
+ Date: self.date_to_bytes,
+ Double: self.double_to_bytes,
+ AnyXml: self.any_xml_to_bytes,
+ Unicode: self.unicode_to_bytes,
+ Boolean: self.boolean_to_bytes,
+ Decimal: self.decimal_to_bytes,
+ Integer: self.integer_to_bytes,
+ AnyHtml: self.any_html_to_bytes,
+ DateTime: self.datetime_to_bytes,
+ Duration: self.duration_to_bytes,
+ ByteArray: self.byte_array_to_bytes,
+ XmlAttribute: self.xmlattribute_to_bytes,
+ ComplexModelBase: self.complex_model_base_to_bytes,
+ }
+ )
+
+ self._to_unicode_handlers = cdict(
+ {
+ ModelBase: self.model_base_to_unicode,
+ File: self.file_to_unicode,
+ Time: self.time_to_unicode,
+ Date: self.date_to_unicode,
+ Uuid: self.uuid_to_unicode,
+ Null: self.null_to_unicode,
+ Double: self.double_to_unicode,
+ AnyXml: self.any_xml_to_unicode,
+ AnyUri: self.any_uri_to_unicode,
+ AnyDict: self.any_dict_to_unicode,
+ AnyHtml: self.any_html_to_unicode,
+ Unicode: self.unicode_to_unicode,
+ Boolean: self.boolean_to_unicode,
+ Decimal: self.decimal_to_unicode,
+ Integer: self.integer_to_unicode,
+ # FIXME: Would we need a to_unicode for localized dates?
+ DateTime: self.datetime_to_unicode,
+ Duration: self.duration_to_unicode,
+ ByteArray: self.byte_array_to_unicode,
+ XmlAttribute: self.xmlattribute_to_unicode,
+ ComplexModelBase: self.complex_model_base_to_unicode,
+ }
+ )
+
+ self._to_bytes_iterable_handlers = cdict(
+ {
+ File: self.file_to_bytes_iterable,
+ ByteArray: self.byte_array_to_bytes_iterable,
+ ModelBase: self.model_base_to_bytes_iterable,
+ SimpleModel: self.simple_model_to_bytes_iterable,
+ ComplexModelBase: self.complex_model_to_bytes_iterable,
+ }
+ )
def serialize(self, ctx, message):
"""Serializes ``ctx.out_object``.
@@ -181,8 +216,9 @@ def fault_to_http_response_code(self, fault):
if isinstance(fault, InvalidCredentialsError):
return HTTP_401
- if isinstance(fault, Fault) and (fault.faultcode.startswith('Client.')
- or fault.faultcode == 'Client'):
+ if isinstance(fault, Fault) and (
+ fault.faultcode.startswith("Client.") or fault.faultcode == "Client"
+ ):
return HTTP_400
return HTTP_500
@@ -202,11 +238,6 @@ def to_bytes(self, cls, value, *args, **kwargs):
handler = self._to_bytes_handlers[cls]
retval = handler(cls, value, *args, **kwargs)
- # enable this only for testing. we're not as strict for performance
- # reasons
- # assert isinstance(retval, six.binary_type), \
- # "AssertionError: %r %r %r handler: %r" % \
- # (type(retval), six.binary_type, retval, handler)
return retval
def to_unicode(self, cls, value, *args, **kwargs):
@@ -219,7 +250,7 @@ def to_unicode(self, cls, value, *args, **kwargs):
# enable this only for testing. we're not as strict for performance
# reasons as well as not to take the joy of dealing with duck typing
# from the user
- # assert isinstance(retval, six.text_type), \
+ # assert isinstance(retval, str), \
# "AssertionError: %r %r handler: %r" % \
# (type(retval), retval, handler)
@@ -239,13 +270,13 @@ def null_to_bytes(self, cls, value, **_):
return b""
def null_to_unicode(self, cls, value, **_):
- return u""
+ return ""
def any_xml_to_bytes(self, cls, value, **_):
return etree.tostring(value)
def any_xml_to_unicode(self, cls, value, **_):
- return etree.tostring(value, encoding='unicode')
+ return etree.tostring(value, encoding="unicode")
def any_dict_to_unicode(self, cls, value, **_):
return repr(value)
@@ -254,17 +285,18 @@ def any_html_to_bytes(self, cls, value, **_):
return html.tostring(value)
def any_html_to_unicode(self, cls, value, **_):
- return html.tostring(value, encoding='unicode')
+ return html.tostring(value, encoding="unicode")
def uuid_to_bytes(self, cls, value, suggested_encoding=None, **_):
ser_as = self.get_cls_attrs(cls).serialize_as
- retval = self.uuid_to_unicode(cls, value,
- suggested_encoding=suggested_encoding, **_)
+ retval = self.uuid_to_unicode(
+ cls, value, suggested_encoding=suggested_encoding, **_
+ )
- if ser_as in ('bytes', 'bytes_le', 'fields', 'int', six.binary_type):
+ if ser_as in ("bytes", "bytes_le", "fields", "int", bytes):
return retval
- return retval.encode('ascii')
+ return retval.encode("ascii")
def uuid_to_unicode(self, cls, value, suggested_encoding=None, **_):
attr = self.get_cls_attrs(cls)
@@ -275,7 +307,7 @@ def uuid_to_unicode(self, cls, value, suggested_encoding=None, **_):
encoding = suggested_encoding
retval = _uuid_serialize[ser_as](value)
- if ser_as in ('bytes', 'bytes_le'):
+ if ser_as in ("bytes", "bytes_le"):
retval = binary_encoding_handlers[encoding]((retval,))
return retval
@@ -284,14 +316,18 @@ def unicode_to_bytes(self, cls, value, **_):
cls_attrs = self.get_cls_attrs(cls)
- if isinstance(value, six.text_type):
+ if isinstance(value, str):
if cls_attrs.encoding is not None:
retval = value.encode(cls_attrs.encoding)
elif self.default_string_encoding is not None:
retval = value.encode(self.default_string_encoding)
- elif not six.PY2:
- logger.warning("You need to set either an encoding for %r "
- "or a default_string_encoding for %r", cls, self)
+ else:
+ logger.warning(
+ "You need to set either an encoding for %r "
+ "or a default_string_encoding for %r",
+ cls,
+ self,
+ )
if cls_attrs.str_format is not None:
return cls_attrs.str_format.format(value)
@@ -308,16 +344,20 @@ def unicode_to_unicode(self, cls, value, **_): # :)))
retval = value
- if isinstance(value, six.binary_type):
+ if isinstance(value, bytes):
if cls_attrs.encoding is not None:
retval = value.decode(cls_attrs.encoding)
if self.default_string_encoding is not None:
retval = value.decode(self.default_string_encoding)
- elif not six.PY2:
- logger.warning("You need to set either an encoding for %r "
- "or a default_string_encoding for %r", cls, self)
+ else:
+ logger.warning(
+ "You need to set either an encoding for %r "
+ "or a default_string_encoding for %r",
+ cls,
+ self,
+ )
if cls_attrs.str_format is not None:
return cls_attrs.str_format.format(value)
@@ -327,7 +367,7 @@ def unicode_to_unicode(self, cls, value, **_): # :)))
return retval
def decimal_to_bytes(self, cls, value, **_):
- return self.decimal_to_unicode(cls, value, **_).encode('utf8')
+ return self.decimal_to_unicode(cls, value, **_).encode("utf8")
def decimal_to_unicode(self, cls, value, **_):
D(value) # sanity check
@@ -341,10 +381,10 @@ def decimal_to_unicode(self, cls, value, **_):
return str(value)
def double_to_bytes(self, cls, value, **_):
- return self.double_to_unicode(cls, value, **_).encode('utf8')
+ return self.double_to_unicode(cls, value, **_).encode("utf8")
def double_to_unicode(self, cls, value, **_):
- float(value) # sanity check
+ float(value) # sanity check
cls_attrs = self.get_cls_attrs(cls)
if cls_attrs.str_format is not None:
@@ -355,7 +395,7 @@ def double_to_unicode(self, cls, value, **_):
return repr(value)
def integer_to_bytes(self, cls, value, **_):
- return self.integer_to_unicode(cls, value, **_).encode('utf8')
+ return self.integer_to_unicode(cls, value, **_).encode("utf8")
def integer_to_unicode(self, cls, value, **_):
int(value) # sanity check
@@ -386,7 +426,7 @@ def date_to_unicode(self, cls, val, **_):
sa = self.get_cls_attrs(cls).serialize_as
- if sa is None or sa in (str, 'str'):
+ if sa is None or sa in (str, "str"):
return self._date_to_bytes(cls, val)
return _datetime_smap[sa](cls, val)
@@ -394,14 +434,14 @@ def date_to_unicode(self, cls, val, **_):
def datetime_to_bytes(self, cls, val, **_):
retval = self.datetime_to_unicode(cls, val, **_)
sa = self.get_cls_attrs(cls).serialize_as
- if sa is None or sa in (six.text_type, str, 'str'):
- return retval.encode('ascii')
+ if sa is None or sa in (str, str, "str"):
+ return retval.encode("ascii")
return retval
def datetime_to_unicode(self, cls, val, **_):
sa = self.get_cls_attrs(cls).serialize_as
- if sa is None or sa in (six.text_type, str, 'str'):
+ if sa is None or sa in (str, str, "str"):
return self._datetime_to_unicode(cls, val)
return _datetime_smap[sa](cls, val)
@@ -433,9 +473,9 @@ def duration_to_unicode(self, cls, value, **_):
retval.append("%iD" % value.days)
if tot_sec != 0 and tot_sec % 86400 == 0 and useconds == 0:
- return ''.join(retval)
+ return "".join(retval)
- retval.append('T')
+ retval.append("T")
if hours > 0:
retval.append("%iH" % hours)
@@ -450,12 +490,12 @@ def duration_to_unicode(self, cls, value, **_):
retval.append("S")
if len(retval) == 2:
- retval.append('0S')
+ retval.append("0S")
- return ''.join(retval)
+ return "".join(retval)
def boolean_to_bytes(self, cls, value, **_):
- return str(bool(value)).lower().encode('ascii')
+ return str(bool(value)).lower().encode("ascii")
def boolean_to_unicode(self, cls, value, **_):
return str(bool(value)).lower()
@@ -470,16 +510,19 @@ def byte_array_to_bytes(self, cls, value, suggested_encoding=None, **_):
else:
encoding = suggested_encoding
- if encoding is None and isinstance(value, (list, tuple)) \
- and len(value) == 1 and isinstance(value[0], mmap):
+ if (
+ encoding is None
+ and isinstance(value, (list, tuple))
+ and len(value) == 1
+ and isinstance(value[0], mmap)
+ ):
return value[0]
encoder = binary_encoding_handlers[encoding]
- logger.debug("Using binary encoder %r for encoding %r",
- encoder, encoding)
+ logger.debug("Using binary encoder %r for encoding %r", encoder, encoding)
retval = encoder(value)
- if encoding is not None and isinstance(retval, six.text_type):
- retval = retval.encode('ascii')
+ if encoding is not None and isinstance(retval, str):
+ retval = retval.encode("ascii")
return retval
@@ -492,12 +535,11 @@ def byte_array_to_unicode(self, cls, value, suggested_encoding=None, **_):
encoding = suggested_encoding
if encoding is None:
- raise ValueError("Arbitrary binary data can't be serialized to "
- "unicode")
+ raise ValueError("Arbitrary binary data can't be serialized to " "unicode")
retval = binary_encoding_handlers[encoding](value)
- if not isinstance(retval, six.text_type):
- retval = retval.decode('ascii')
+ if not isinstance(retval, str):
+ retval = retval.decode("ascii")
return retval
@@ -524,24 +566,21 @@ def file_to_bytes(self, cls, value, suggested_encoding=None):
if value.handle is not None:
# maybe we should have used the sweeping except: here.
- if hasattr(value.handle, 'fileno'):
- if six.PY2:
+ if hasattr(value.handle, "fileno"):
+ import io
+
+ try:
fileno = value.handle.fileno()
- data = (mmap(fileno, 0, access=ACCESS_READ),)
- else:
- import io
- try:
- fileno = value.handle.fileno()
- data = mmap(fileno, 0, access=ACCESS_READ)
- except io.UnsupportedOperation:
- data = (value.handle.read(),)
+ data = mmap(fileno, 0, access=ACCESS_READ)
+ except io.UnsupportedOperation:
+ data = (value.handle.read(),)
else:
data = (value.handle.read(),)
return binary_encoding_handlers[encoding](data)
if value.path is not None:
- handle = open(value.path, 'rb')
+ handle = open(value.path, "rb")
fileno = handle.fileno()
data = mmap(fileno, 0, access=ACCESS_READ)
@@ -553,15 +592,17 @@ def file_to_bytes(self, cls, value, suggested_encoding=None):
try:
return binary_encoding_handlers[encoding](value.data)
except Exception as e:
- logger.error("Error encoding value to binary. Error: %r, Value: %r",
- e, value)
+ logger.error(
+ "Error encoding value to binary. Error: %r, Value: %r", e, value
+ )
raise
try:
return binary_encoding_handlers[encoding](value)
except Exception as e:
- logger.error("Error encoding value to binary. Error: %r, Value: %r",
- e, value)
+ logger.error(
+ "Error encoding value to binary. Error: %r, Value: %r", e, value
+ )
raise
def file_to_unicode(self, cls, value, suggested_encoding=None):
@@ -577,18 +618,18 @@ def file_to_unicode(self, cls, value, suggested_encoding=None):
encoding = suggested_encoding
if encoding is None and cls_attrs.mode is File.TEXT:
- raise ValueError("Arbitrary binary data can't be serialized to "
- "unicode.")
+ raise ValueError("Arbitrary binary data can't be serialized to " "unicode.")
retval = self.file_to_bytes(cls, value, suggested_encoding)
- if not isinstance(retval, six.text_type):
- retval = retval.decode('ascii')
+ if not isinstance(retval, str):
+ retval = retval.decode("ascii")
return retval
def file_to_bytes_iterable(self, cls, value, **_):
if value.data is not None:
- if isinstance(value.data, (list, tuple)) and \
- isinstance(value.data[0], mmap):
+ if isinstance(value.data, (list, tuple)) and isinstance(
+ value.data[0], mmap
+ ):
return _file_to_iter(value.data[0])
return iter(value.data)
@@ -597,16 +638,19 @@ def file_to_bytes_iterable(self, cls, value, **_):
f.seek(0)
return _file_to_iter(f)
- assert value.path is not None, "You need to write data to " \
- "persistent storage first if you want to read it back."
+ assert value.path is not None, (
+ "You need to write data to "
+ "persistent storage first if you want to read it back."
+ )
try:
path = value.path
if not isabs(value.path):
path = join(value.store, value.path)
- assert abspath(path).startswith(value.store), \
- "No relative paths are allowed"
- return _file_to_iter(open(path, 'rb'))
+ assert abspath(path).startswith(
+ value.store
+ ), "No relative paths are allowed"
+ return _file_to_iter(open(path, "rb"))
except IOError as e:
if e.errno == errno.ENOENT:
@@ -617,7 +661,7 @@ def file_to_bytes_iterable(self, cls, value, **_):
def simple_model_to_bytes_iterable(self, cls, value, **kwargs):
retval = self.to_bytes(cls, value, **kwargs)
if retval is None:
- return (b'',)
+ return (b"",)
return (retval,)
def complex_model_to_bytes_iterable(self, cls, value, **_):
@@ -662,9 +706,6 @@ def _datetime_to_unicode(self, cls, value, **_):
if dt_format is None:
retval = value.isoformat()
- elif six.PY2 and isinstance(dt_format, unicode):
- retval = self.strftime(value, dt_format.encode('utf8')).decode('utf8')
-
else:
retval = self.strftime(value, dt_format)
@@ -689,10 +730,6 @@ def _date_to_bytes(self, cls, value, **_):
if date_format is None:
retval = value.isoformat()
- elif six.PY2 and isinstance(date_format, unicode):
- date_format = date_format.encode('utf8')
- retval = self.strftime(value, date_format).decode('utf8')
-
else:
retval = self.strftime(value, date_format)
@@ -715,7 +752,6 @@ def _date_to_bytes(self, cls, value, **_):
# '1850/00/02 was a Friday'
# >>>
-
# remove the unsupposed "%s" command. But don't
# do it if there's an even number of %s before the s
# because those are all escaped. Can't simply
@@ -727,16 +763,16 @@ def _date_to_bytes(self, cls, value, **_):
@staticmethod
def _findall_datetime(text, substr):
- # Also finds overlaps
- sites = []
- i = 0
- while 1:
- j = text.find(substr, i)
- if j == -1:
- break
- sites.append(j)
- i=j+1
- return sites
+ # Also finds overlaps
+ sites = []
+ i = 0
+ while 1:
+ j = text.find(substr, i)
+ if j == -1:
+ break
+ sites.append(j)
+ i = j + 1
+ return sites
# Every 28 years the calendar repeats, except through century leap
# years where it's 6 years. But only if you're using the Gregorian
@@ -753,7 +789,7 @@ def strftime(cls, dt, fmt):
# For every non-leap year century, advance by
# 6 years to get into the 28-year repeat cycle
delta = 2000 - year
- off = 6*(delta // 100 + delta // 400)
+ off = 6 * (delta // 100 + delta // 400)
year += off
# Move to around the year 2000
@@ -762,8 +798,8 @@ def strftime(cls, dt, fmt):
s1 = strftime(fmt, (year,) + timetuple[1:])
sites1 = cls._findall_datetime(s1, str(year))
- s2 = strftime(fmt, (year+28,) + timetuple[1:])
- sites2 = cls._findall_datetime(s2, str(year+28))
+ s2 = strftime(fmt, (year + 28,) + timetuple[1:])
+ sites2 = cls._findall_datetime(s2, str(year + 28))
sites = []
for site in sites1:
@@ -773,60 +809,50 @@ def strftime(cls, dt, fmt):
s = s1
syear = "%4d" % (dt.year,)
for site in sites:
- s = s[:site] + syear + s[site+4:]
+ s = s[:site] + syear + s[site + 4 :]
return s
_uuid_serialize = {
None: str,
str: str,
- 'str': str,
-
- 'hex': lambda u: u.hex,
- 'urn': lambda u: u.urn,
- 'bytes': lambda u: u.bytes,
- 'bytes_le': lambda u: u.bytes_le,
- 'fields': lambda u: u.fields,
-
+ "str": str,
+ "hex": lambda u: u.hex,
+ "urn": lambda u: u.urn,
+ "bytes": lambda u: u.bytes,
+ "bytes_le": lambda u: u.bytes_le,
+ "fields": lambda u: u.fields,
int: lambda u: u.int,
- 'int': lambda u: u.int,
+ "int": lambda u: u.int,
}
_uuid_deserialize = {
None: uuid.UUID,
str: uuid.UUID,
- 'str': uuid.UUID,
-
- 'hex': lambda s: uuid.UUID(hex=s),
- 'urn': lambda s: uuid.UUID(hex=s),
- 'bytes': lambda s: uuid.UUID(bytes=s),
- 'bytes_le': lambda s: uuid.UUID(bytes_le=s),
- 'fields': lambda s: uuid.UUID(fields=s),
-
+ "str": uuid.UUID,
+ "hex": lambda s: uuid.UUID(hex=s),
+ "urn": lambda s: uuid.UUID(hex=s),
+ "bytes": lambda s: uuid.UUID(bytes=s),
+ "bytes_le": lambda s: uuid.UUID(bytes_le=s),
+ "fields": lambda s: uuid.UUID(fields=s),
int: lambda s: uuid.UUID(int=s),
- 'int': lambda s: uuid.UUID(int=s),
-
+ "int": lambda s: uuid.UUID(int=s),
(int, int): lambda s: uuid.UUID(int=s),
- ('int', int): lambda s: uuid.UUID(int=s),
-
+ ("int", int): lambda s: uuid.UUID(int=s),
(int, str): lambda s: uuid.UUID(int=int(s)),
- ('int', str): lambda s: uuid.UUID(int=int(s)),
+ ("int", str): lambda s: uuid.UUID(int=int(s)),
}
-if six.PY2:
- _uuid_deserialize[('int', long)] = _uuid_deserialize[('int', int)]
- _uuid_deserialize[(int, long)] = _uuid_deserialize[('int', int)]
-
def _parse_datetime_iso_match(date_match, tz=None):
fields = date_match.groupdict()
- year = int(fields.get('year'))
- month = int(fields.get('month'))
- day = int(fields.get('day'))
- hour = int(fields.get('hr'))
- minute = int(fields.get('min'))
- second = int(fields.get('sec'))
+ year = int(fields.get("year"))
+ month = int(fields.get("month"))
+ day = int(fields.get("day"))
+ hour = int(fields.get("hr"))
+ minute = int(fields.get("min"))
+ second = int(fields.get("sec"))
usecond = fields.get("sec_frac")
if usecond is None:
usecond = 0
@@ -838,50 +864,45 @@ def _parse_datetime_iso_match(date_match, tz=None):
return datetime(year, month, day, hour, minute, second, usecond, tz)
-_dt_sec = lambda cls, val: \
- int(mktime(val.timetuple()))
-_dt_sec_float = lambda cls, val: \
- mktime(val.timetuple()) + (val.microsecond / 1e6)
+_dt_sec = lambda cls, val: int(mktime(val.timetuple()))
+_dt_sec_float = lambda cls, val: mktime(val.timetuple()) + (val.microsecond / 1e6)
-_dt_msec = lambda cls, val: \
- int(mktime(val.timetuple())) * 1000 + (val.microsecond // 1000)
-_dt_msec_float = lambda cls, val: \
- mktime(val.timetuple()) * 1000 + (val.microsecond / 1000.0)
+_dt_msec = lambda cls, val: int(mktime(val.timetuple())) * 1000 + (
+ val.microsecond // 1000
+)
+_dt_msec_float = lambda cls, val: mktime(val.timetuple()) * 1000 + (
+ val.microsecond / 1000.0
+)
-_dt_usec = lambda cls, val: \
- int(mktime(val.timetuple())) * 1000000 + val.microsecond
+_dt_usec = lambda cls, val: int(mktime(val.timetuple())) * 1000000 + val.microsecond
_datetime_smap = {
- 'sec': _dt_sec,
- 'secs': _dt_sec,
- 'second': _dt_sec,
- 'seconds': _dt_sec,
-
- 'sec_float': _dt_sec_float,
- 'secs_float': _dt_sec_float,
- 'second_float': _dt_sec_float,
- 'seconds_float': _dt_sec_float,
-
- 'msec': _dt_msec,
- 'msecs': _dt_msec,
- 'msecond': _dt_msec,
- 'mseconds': _dt_msec,
- 'millisecond': _dt_msec,
- 'milliseconds': _dt_msec,
-
- 'msec_float': _dt_msec_float,
- 'msecs_float': _dt_msec_float,
- 'msecond_float': _dt_msec_float,
- 'mseconds_float': _dt_msec_float,
- 'millisecond_float': _dt_msec_float,
- 'milliseconds_float': _dt_msec_float,
-
- 'usec': _dt_usec,
- 'usecs': _dt_usec,
- 'usecond': _dt_usec,
- 'useconds': _dt_usec,
- 'microsecond': _dt_usec,
- 'microseconds': _dt_usec,
+ "sec": _dt_sec,
+ "secs": _dt_sec,
+ "second": _dt_sec,
+ "seconds": _dt_sec,
+ "sec_float": _dt_sec_float,
+ "secs_float": _dt_sec_float,
+ "second_float": _dt_sec_float,
+ "seconds_float": _dt_sec_float,
+ "msec": _dt_msec,
+ "msecs": _dt_msec,
+ "msecond": _dt_msec,
+ "mseconds": _dt_msec,
+ "millisecond": _dt_msec,
+ "milliseconds": _dt_msec,
+ "msec_float": _dt_msec_float,
+ "msecs_float": _dt_msec_float,
+ "msecond_float": _dt_msec_float,
+ "mseconds_float": _dt_msec_float,
+ "millisecond_float": _dt_msec_float,
+ "milliseconds_float": _dt_msec_float,
+ "usec": _dt_usec,
+ "usecs": _dt_usec,
+ "usecond": _dt_usec,
+ "useconds": _dt_usec,
+ "microsecond": _dt_usec,
+ "microseconds": _dt_usec,
}
@@ -896,4 +917,4 @@ def _file_to_iter(f):
f.close()
-META_ATTR = ['nullable', 'default_factory']
+META_ATTR = ["nullable", "default_factory"]
diff --git a/spyne/protocol/cloth/__init__.py b/spyne/protocol/cloth/__init__.py
index 2bf9b9350..0d00719d5 100644
--- a/spyne/protocol/cloth/__init__.py
+++ b/spyne/protocol/cloth/__init__.py
@@ -21,6 +21,6 @@
for clothing otherwise boring data.
"""
-from spyne.protocol.cloth._base import XmlCloth
# huge hack to have the last line of microformat.py execute
import spyne.protocol.html
+from spyne.protocol.cloth._base import XmlCloth
diff --git a/spyne/protocol/cloth/_base.py b/spyne/protocol/cloth/_base.py
index 4ea7fe636..3b26127e7 100644
--- a/spyne/protocol/cloth/_base.py
+++ b/spyne/protocol/cloth/_base.py
@@ -20,21 +20,24 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
from inspect import isgenerator
+from io import BytesIO
from lxml import etree
from lxml.etree import LxmlSyntaxError
-from spyne import ProtocolContext, BODY_STYLE_WRAPPED, ByteArray, File, Array
-from spyne.util import Break, coroutine
+from spyne.context import ProtocolContext
+from spyne.descriptor import BODY_STYLE_WRAPPED
+from spyne.model.binary import ByteArray, File
+from spyne.model.complex import Array
from spyne.protocol import ProtocolMixin
-
-from spyne.protocol.cloth.to_parent import ToParentMixin
from spyne.protocol.cloth.to_cloth import ToClothMixin
-from spyne.util.six import BytesIO
-from spyne.util.color import R, B
+from spyne.protocol.cloth.to_parent import ToParentMixin
+from spyne.util import Break, coroutine
+from spyne.util.color import B, R
from spyne.util.tlist import tlist
@@ -48,22 +51,37 @@ def __init__(self, parent, transport, type=None):
class XmlCloth(ToParentMixin, ToClothMixin):
- mime_type = 'text/xml'
+ mime_type = "text/xml"
HtmlMicroFormat = None
- def __init__(self, app=None, encoding='utf8', doctype=None,
- mime_type=None, ignore_uncap=False, ignore_wrappers=False,
- cloth=None, cloth_parser=None, polymorphic=True,
- strip_comments=True, use_ns=None, skip_root_tag=False):
-
- super(XmlCloth, self).__init__(app=app, mime_type=mime_type,
- ignore_uncap=ignore_uncap, ignore_wrappers=ignore_wrappers,
- polymorphic=polymorphic)
+ def __init__(
+ self,
+ app=None,
+ encoding="utf8",
+ doctype=None,
+ mime_type=None,
+ ignore_uncap=False,
+ ignore_wrappers=False,
+ cloth=None,
+ cloth_parser=None,
+ polymorphic=True,
+ strip_comments=True,
+ use_ns=None,
+ skip_root_tag=False,
+ ):
+
+ super(XmlCloth, self).__init__(
+ app=app,
+ mime_type=mime_type,
+ ignore_uncap=ignore_uncap,
+ ignore_wrappers=ignore_wrappers,
+ polymorphic=polymorphic,
+ )
self._init_cloth(cloth, cloth_parser, strip_comments)
self.developer_mode = False
self.encoding = encoding
- self.default_method = 'xml'
+ self.default_method = "xml"
self.doctype = doctype
self.use_ns = use_ns
self.skip_root_tag = skip_root_tag
@@ -81,7 +99,7 @@ def serialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_serialize', ctx)
+ self.event_manager.fire_event("before_serialize", ctx)
if ctx.out_stream is None:
ctx.out_stream = BytesIO()
@@ -110,23 +128,24 @@ def serialize(self, ctx, message):
if ctx.descriptor.body_style == BODY_STYLE_WRAPPED:
if self.ignore_wrappers:
result_inst = ctx.out_object[0]
- while result_class.Attributes._wrapper and \
- len(result_class._type_info) == 1:
- result_class, = result_class._type_info.values()
+ while (
+ result_class.Attributes._wrapper
+ and len(result_class._type_info) == 1
+ ):
+ (result_class,) = result_class._type_info.values()
else:
result_inst = result_class()
- for i, attr_name in enumerate(
- result_class._type_info.keys()):
+ for i, attr_name in enumerate(result_class._type_info.keys()):
setattr(result_inst, attr_name, ctx.out_object[i])
else:
- result_inst, = ctx.out_object
+ (result_inst,) = ctx.out_object
retval = self._incgen(ctx, result_class, result_inst, name)
- self.event_manager.fire_event('after_serialize', ctx)
+ self.event_manager.fire_event("after_serialize", ctx)
return retval
@@ -159,7 +178,7 @@ def _incgen(self, ctx, cls, inst, name):
if isgenerator(ret): # Poor man's yield from
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as b:
@@ -169,7 +188,7 @@ def _incgen(self, ctx, cls, inst, name):
pass
except LxmlSyntaxError as e:
- if e.msg == 'no content written':
+ if e.msg == "no content written":
pass
else:
raise
@@ -210,26 +229,24 @@ def get_class_root_cloth(cls):
def check_class_cloths(self, ctx, cls, inst, parent, name, **kwargs):
c = self.get_class_root_cloth(cls)
- eltstack = getattr(ctx.protocol, 'eltstack', [])
+ eltstack = getattr(ctx.protocol, "eltstack", [])
if c is not None and len(eltstack) == 0 and not (eltstack[-1] is c):
if not ctx.outprot_ctx.doctype_written:
self.write_doctype(ctx, parent, c)
logger.debug("to object root cloth")
- return True, self.to_root_cloth(ctx, cls, inst, c, parent, name,
- **kwargs)
+ return True, self.to_root_cloth(ctx, cls, inst, c, parent, name, **kwargs)
c = self.get_class_cloth(cls)
if c is not None:
if not ctx.outprot_ctx.doctype_written:
self.write_doctype(ctx, parent, c)
logger.debug("to object cloth")
- return True, self.to_parent_cloth(ctx, cls, inst, c, parent, name,
- **kwargs)
+ return True, self.to_parent_cloth(ctx, cls, inst, c, parent, name, **kwargs)
return False, None
@coroutine
- def subserialize(self, ctx, cls, inst, parent, name='', **kwargs):
+ def subserialize(self, ctx, cls, inst, parent, name="", **kwargs):
"""Bridge between multiple XmlCloth-based protocols.
Not supposed to be overridden.
@@ -248,14 +265,12 @@ def subserialize(self, ctx, cls, inst, parent, name='', **kwargs):
elif self._root_cloth is not None:
logger.debug("to root cloth for %s", cls.get_type_name())
- ret = self.to_root_cloth(ctx, cls, inst, self._root_cloth,
- parent, name)
+ ret = self.to_root_cloth(ctx, cls, inst, self._root_cloth, parent, name)
have_cloth = True
elif self._cloth is not None:
logger.debug("to parent protocol cloth for %s", cls.get_type_name())
- ret = self.to_parent_cloth(ctx, cls, inst, self._cloth, parent,
- name)
+ ret = self.to_parent_cloth(ctx, cls, inst, self._cloth, parent, name)
have_cloth = True
else:
@@ -265,7 +280,7 @@ def subserialize(self, ctx, cls, inst, parent, name='', **kwargs):
if isgenerator(ret): # Poor man's yield from
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as b:
@@ -312,8 +327,7 @@ def _gen_attrib_dict(self, inst, fti):
sub_name = self._gen_tagname(ns, sub_name)
if issubclass(field_type.type, (ByteArray, File)):
- valstr = self.to_unicode(field_type.type, val,
- self.binary_encoding)
+ valstr = self.to_unicode(field_type.type, val, self.binary_encoding)
else:
valstr = self.to_unicode(field_type.type, val)
diff --git a/spyne/protocol/cloth/to_cloth.py b/spyne/protocol/cloth/to_cloth.py
index 6dd59cd77..1ad6f894c 100644
--- a/spyne/protocol/cloth/to_cloth.py
+++ b/spyne/protocol/cloth/to_cloth.py
@@ -21,22 +21,32 @@
from __future__ import print_function
import logging
+
logger_c = logging.getLogger("%s.cloth" % __name__)
logger_s = logging.getLogger("%s.serializer" % __name__)
-from lxml import html, etree
from copy import deepcopy
from inspect import isgenerator
-from spyne.util import Break, coroutine
-from spyne.util.oset import oset
-from spyne.util.six import string_types
-from spyne.util.color import R, B
-from spyne.model import Array, AnyXml, AnyHtml, ModelBase, ComplexModelBase, \
- PushBase, XmlAttribute, AnyUri, XmlData, Any
-
+from lxml import etree, html
+
+from spyne.model import (
+ Any,
+ AnyHtml,
+ AnyUri,
+ AnyXml,
+ Array,
+ ComplexModelBase,
+ ModelBase,
+ PushBase,
+ XmlAttribute,
+ XmlData,
+)
from spyne.protocol import OutProtocolBase
+from spyne.util import Break, coroutine
from spyne.util.cdict import cdict
+from spyne.util.color import B, R
+from spyne.util.oset import oset
_revancestors = lambda elt: list(reversed(tuple(elt.iterancestors())))
@@ -56,7 +66,7 @@ def _prevsibls_since(elt, strip_comments, since):
break
if strip_comments and isinstance(elt, etree.CommentBase):
- if elt.text.startswith('[if ') and elt.text.endswith('[endif]'):
+ if elt.text.startswith("[if ") and elt.text.endswith("[endif]"):
pass
else:
continue
@@ -64,20 +74,28 @@ def _prevsibls_since(elt, strip_comments, since):
yield prevsibl
-def _set_identifier_prefix(obj, prefix, mrpc_id='mrpc', id_attr='id',
- data_tag='data', data_attr='data', attr_attr='attr',
- root_attr='root', tagbag_attr='tagbag'):
+def _set_identifier_prefix(
+ obj,
+ prefix,
+ mrpc_id="mrpc",
+ id_attr="id",
+ data_tag="data",
+ data_attr="data",
+ attr_attr="attr",
+ root_attr="root",
+ tagbag_attr="tagbag",
+):
obj.ID_PREFIX = prefix
- obj.MRPC_ID = '{}{}'.format(prefix, mrpc_id)
- obj.ID_ATTR_NAME = '{}{}'.format(prefix, id_attr)
- obj.DATA_TAG_NAME = '{}{}'.format(prefix, data_tag)
- obj.DATA_ATTR_NAME = '{}{}'.format(prefix, data_attr)
- obj.ATTR_ATTR_NAME = '{}{}'.format(prefix, attr_attr)
- obj.ROOT_ATTR_NAME = '{}{}'.format(prefix, root_attr)
- obj.TAGBAG_ATTR_NAME = '{}{}'.format(prefix, tagbag_attr)
+ obj.MRPC_ID = "{}{}".format(prefix, mrpc_id)
+ obj.ID_ATTR_NAME = "{}{}".format(prefix, id_attr)
+ obj.DATA_TAG_NAME = "{}{}".format(prefix, data_tag)
+ obj.DATA_ATTR_NAME = "{}{}".format(prefix, data_attr)
+ obj.ATTR_ATTR_NAME = "{}{}".format(prefix, attr_attr)
+ obj.ROOT_ATTR_NAME = "{}{}".format(prefix, root_attr)
+ obj.TAGBAG_ATTR_NAME = "{}{}".format(prefix, tagbag_attr)
# FIXME: get rid of this. We don't want logic creep inside cloths
- obj.WRITE_CONTENTS_WHEN_NOT_NONE = '{}write-contents'.format(prefix)
+ obj.WRITE_CONTENTS_WHEN_NOT_NONE = "{}write-contents".format(prefix)
obj.SPYNE_ATTRS = {
obj.ID_ATTR_NAME,
@@ -90,17 +108,17 @@ def _set_identifier_prefix(obj, prefix, mrpc_id='mrpc', id_attr='id',
class ClothParserMixin(object):
- ID_PREFIX = 'spyne-'
+ ID_PREFIX = "spyne-"
# these are here for documentation purposes. The are all reinitialized with
# the call ta _set_identifier_prefix below the class definition
- ID_ATTR_NAME = 'spyne-id'
- DATA_TAG_NAME = 'spyne-data'
- DATA_ATTR_NAME = 'spyne-data'
- ATTR_ATTR_NAME = 'spyne-attr'
- ROOT_ATTR_NAME = 'spyne-root'
- TAGBAG_ATTR_NAME = 'spyne-tagbag'
- WRITE_CONTENTS_WHEN_NOT_NONE = 'spyne-write-contents'
+ ID_ATTR_NAME = "spyne-id"
+ DATA_TAG_NAME = "spyne-data"
+ DATA_ATTR_NAME = "spyne-data"
+ ATTR_ATTR_NAME = "spyne-attr"
+ ROOT_ATTR_NAME = "spyne-root"
+ TAGBAG_ATTR_NAME = "spyne-tagbag"
+ WRITE_CONTENTS_WHEN_NOT_NONE = "spyne-write-contents"
def set_identifier_prefix(self, what):
_set_identifier_prefix(self, what)
@@ -109,15 +127,17 @@ def set_identifier_prefix(self, what):
@classmethod
def from_xml_cloth(cls, cloth, strip_comments=True):
retval = cls()
- retval._init_cloth(cloth, cloth_parser=etree.XMLParser(),
- strip_comments=strip_comments)
+ retval._init_cloth(
+ cloth, cloth_parser=etree.XMLParser(), strip_comments=strip_comments
+ )
return retval
@classmethod
def from_html_cloth(cls, cloth, strip_comments=True):
retval = cls()
- retval._init_cloth(cloth, cloth_parser=html.HTMLParser(),
- strip_comments=strip_comments)
+ retval._init_cloth(
+ cloth, cloth_parser=html.HTMLParser(), strip_comments=strip_comments
+ )
return retval
@staticmethod
@@ -125,8 +145,7 @@ def _strip_comments(root):
for elt in root.iter():
if isinstance(elt, etree.CommentBase):
if elt.getparent() is not None:
- if elt.text.startswith('[if ') \
- and elt.text.endswith('[endif]'):
+ if elt.text.startswith("[if ") and elt.text.endswith("[endif]"):
pass
else:
elt.getparent().remove(elt)
@@ -148,7 +167,7 @@ def _init_cloth(self, cloth, cloth_parser, strip_comments):
if cloth is None:
return
- if isinstance(cloth, string_types):
+ if isinstance(cloth, str):
cloth = self._parse_file(cloth, cloth_parser)
if strip_comments:
@@ -163,7 +182,7 @@ def _init_cloth(self, cloth, cloth_parser, strip_comments):
logger_c.debug("Using %r as plain cloth.", cloth)
self._cloth = cloth
- self._mrpc_cloth = self._pop_elt(cloth, 'mrpc_entry')
+ self._mrpc_cloth = self._pop_elt(cloth, "mrpc_entry")
def _pop_elt(self, elt, what):
query = '//*[@%s="%s"]' % (self.ID_ATTR_NAME, what)
@@ -181,27 +200,39 @@ def _pop_elt(self, elt, what):
class ToClothMixin(OutProtocolBase, ClothParserMixin):
- def __init__(self, app=None, mime_type=None, ignore_uncap=False,
- ignore_wrappers=False, polymorphic=True):
- super(ToClothMixin, self).__init__(app=app, mime_type=mime_type,
- ignore_uncap=ignore_uncap, ignore_wrappers=ignore_wrappers)
+ def __init__(
+ self,
+ app=None,
+ mime_type=None,
+ ignore_uncap=False,
+ ignore_wrappers=False,
+ polymorphic=True,
+ ):
+ super(ToClothMixin, self).__init__(
+ app=app,
+ mime_type=mime_type,
+ ignore_uncap=ignore_uncap,
+ ignore_wrappers=ignore_wrappers,
+ )
self.polymorphic = polymorphic
- self.rendering_handlers = cdict({
- ModelBase: self.model_base_to_cloth,
- AnyXml: self.xml_to_cloth,
- Any: self.any_to_cloth,
- AnyHtml: self.html_to_cloth,
- AnyUri: self.any_uri_to_cloth,
- ComplexModelBase: self.complex_to_cloth,
- })
+ self.rendering_handlers = cdict(
+ {
+ ModelBase: self.model_base_to_cloth,
+ AnyXml: self.xml_to_cloth,
+ Any: self.any_to_cloth,
+ AnyHtml: self.html_to_cloth,
+ AnyUri: self.any_uri_to_cloth,
+ ComplexModelBase: self.complex_to_cloth,
+ }
+ )
def _get_elts(self, elt, tag_id=None):
if tag_id is None:
- return elt.xpath('.//*[@*[starts-with(name(), "%s")]]' %
- self.ID_PREFIX)
- return elt.xpath('.//*[@*[starts-with(name(), "%s")]="%s"]' % (
- self.ID_PREFIX, tag_id))
+ return elt.xpath('.//*[@*[starts-with(name(), "%s")]]' % self.ID_PREFIX)
+ return elt.xpath(
+ './/*[@*[starts-with(name(), "%s")]="%s"]' % (self.ID_PREFIX, tag_id)
+ )
def _get_outmost_elts(self, tmpl, tag_id=None):
ids = set()
@@ -250,7 +281,7 @@ def _is_tagbag(self, elt):
@staticmethod
def _methods(ctx, cls, inst):
while cls.Attributes._wrapper and len(cls._type_info) > 0:
- cls, = cls._type_info.values()
+ (cls,) = cls._type_info.values()
if cls.Attributes.methods is not None:
for k, v in cls.Attributes.methods.items():
@@ -272,19 +303,21 @@ def _actions_to_cloth(self, ctx, cls, inst, template):
text = v.translate(ctx.locale, v.in_message.get_type_name())
mrpc_template = deepcopy(self._mrpc_cloth)
- anchor = self._get_clean_elt(mrpc_template, 'mrpc_link')
- anchor.attrib['href'] = href
+ anchor = self._get_clean_elt(mrpc_template, "mrpc_link")
+ anchor.attrib["href"] = href
- text_elt = self._get_clean_elt(mrpc_template, 'mrpc_text')
+ text_elt = self._get_clean_elt(mrpc_template, "mrpc_text")
if text_elt is not None:
text_elt.text = text
else:
anchor.text = text
elt.append(mrpc_template)
- # mutable default ok because readonly
- def _enter_cloth(self, ctx, cloth, parent, attrib={}, skip=False,
- method=None, skip_dupe=False):
+ # mutable default ok because readonly
+
+ def _enter_cloth(
+ self, ctx, cloth, parent, attrib={}, skip=False, method=None, skip_dupe=False
+ ):
"""Enters the given tag in the document by using the shortest path from
current tag.
@@ -314,8 +347,15 @@ def _enter_cloth(self, ctx, cloth, parent, attrib={}, skip=False,
(eg. arrays).
"""
- logger_c.debug("entering %s %r nsmap=%r attrib=%r skip=%s method=%s",
- cloth.tag, cloth.attrib, cloth.nsmap, attrib, skip, method)
+ logger_c.debug(
+ "entering %s %r nsmap=%r attrib=%r skip=%s method=%s",
+ cloth.tag,
+ cloth.attrib,
+ cloth.nsmap,
+ attrib,
+ skip,
+ method,
+ )
if not ctx.outprot_ctx.doctype_written:
self.write_doctype(ctx, parent, cloth)
@@ -352,7 +392,7 @@ def _enter_cloth(self, ctx, cloth, parent, attrib={}, skip=False,
# move up in tag stack until the ancestors of both
# source and target tags match
- while ancestors[:len(cureltstack)] != cureltstack:
+ while ancestors[: len(cureltstack)] != cureltstack:
elt = cureltstack.pop()
elt_ctx = curctxstack.pop()
@@ -366,37 +406,43 @@ def _enter_cloth(self, ctx, cloth, parent, attrib={}, skip=False,
# unless we're at the same level as the relevant ancestor of the
# target node
- if ancestors[:len(cureltstack)] != cureltstack:
+ if ancestors[: len(cureltstack)] != cureltstack:
# write following siblings before closing parent node
for sibl in elt.itersiblings(preceding=False):
- logger_c.debug("\twrite exit sibl %s %r %d",
- sibl.tag, sibl.attrib, id(sibl))
+ logger_c.debug(
+ "\twrite exit sibl %s %r %d", sibl.tag, sibl.attrib, id(sibl)
+ )
parent.write(sibl)
# write remaining ancestors of the target node.
- for anc in ancestors[len(cureltstack):]:
+ for anc in ancestors[len(cureltstack) :]:
# write previous siblings of ancestors (if any)
prevsibls = _prevsibls(anc, self.strip_comments, since=last_elt)
for elt in prevsibls:
if id(elt) in tags:
- logger_c.debug("\tskip anc prevsibl %s %r",
- elt.tag, elt.attrib)
+ logger_c.debug("\tskip anc prevsibl %s %r", elt.tag, elt.attrib)
continue
- logger_c.debug("\twrite anc prevsibl %s %r 0x%x",
- elt.tag, elt.attrib, id(elt))
+ logger_c.debug(
+ "\twrite anc prevsibl %s %r 0x%x", elt.tag, elt.attrib, id(elt)
+ )
parent.write(elt)
# enter the ancestor node
kwargs = {}
if len(cureltstack) == 0:
# if this is the first node ever, initialize namespaces as well
- kwargs['nsmap'] = anc.nsmap
+ kwargs["nsmap"] = anc.nsmap
anc_ctx = parent.element(anc.tag, anc.attrib, **kwargs)
anc_ctx.__enter__()
- logger_c.debug("\tenter norm %s %r 0x%x method: %r", anc.tag,
- anc.attrib, id(anc), method)
+ logger_c.debug(
+ "\tenter norm %s %r 0x%x method: %r",
+ anc.tag,
+ anc.attrib,
+ id(anc),
+ method,
+ )
if anc.text is not None:
parent.write(anc.text)
@@ -414,8 +460,7 @@ def _enter_cloth(self, ctx, cloth, parent, attrib={}, skip=False,
continue
if id(elt) in tags:
- logger_c.debug("\tskip cloth prevsibl %s %r",
- elt.tag, elt.attrib)
+ logger_c.debug("\tskip cloth prevsibl %s %r", elt.tag, elt.attrib)
continue
logger_c.debug("\twrite cloth prevsibl %s %r", elt.tag, elt.attrib)
@@ -433,20 +478,22 @@ def _enter_cloth(self, ctx, cloth, parent, attrib={}, skip=False,
else:
# finally, enter the target node.
- cloth_attrib = dict([(k, v) for k, v in cloth.attrib.items()
- if not k in self.SPYNE_ATTRS])
+ cloth_attrib = dict(
+ [(k, v) for k, v in cloth.attrib.items() if not k in self.SPYNE_ATTRS]
+ )
cloth_attrib.update(attrib)
- self.event_manager.fire_event(("before_entry", cloth), ctx,
- parent, cloth_attrib)
+ self.event_manager.fire_event(
+ ("before_entry", cloth), ctx, parent, cloth_attrib
+ )
kwargs = {}
if len(cureltstack) == 0:
# if this is the first node ever, initialize namespaces as well
- kwargs['nsmap'] = cloth.nsmap
+ kwargs["nsmap"] = cloth.nsmap
if method is not None:
- kwargs['method'] = method
+ kwargs["method"] = method
curtag = parent.element(cloth.tag, cloth_attrib, **kwargs)
curtag.__enter__()
if cloth.text is not None:
@@ -492,19 +539,20 @@ def _close_cloth(self, ctx, parent):
rootstack.pop()
@coroutine
- def to_parent_cloth(self, ctx, cls, inst, cloth, parent, name,
- from_arr=False, **kwargs):
+ def to_parent_cloth(
+ self, ctx, cls, inst, cloth, parent, name, from_arr=False, **kwargs
+ ):
cls_cloth = self.get_class_cloth(cls)
if cls_cloth is not None:
logger_c.debug("%r to object cloth", cls)
cloth = cls_cloth
ctx.protocol[self].rootstack.add(cloth)
- ret = self.to_cloth(ctx, cls, inst, cloth, parent, '')
+ ret = self.to_cloth(ctx, cls, inst, cloth, parent, "")
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
try:
@@ -524,7 +572,7 @@ def to_root_cloth(self, ctx, cls, inst, cloth, parent, name):
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
try:
@@ -534,8 +582,19 @@ def to_root_cloth(self, ctx, cls, inst, cloth, parent, name):
# TODO: Maybe DRY this with to_parent?
@coroutine
- def to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
- from_arr=False, as_attr=False, as_data=False, **kwargs):
+ def to_cloth(
+ self,
+ ctx,
+ cls,
+ inst,
+ cloth,
+ parent,
+ name=None,
+ from_arr=False,
+ as_attr=False,
+ as_data=False,
+ **kwargs,
+ ):
prot_name = self.__class__.__name__
@@ -573,15 +632,26 @@ def to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
# we can't do this because subprotocols don't accept cloths.
# so we need to enter the cloth, which make it too late to
# set attributes.
- assert not as_attr, "No subprot supported for fields " \
- "to be serialized as attributes, use type casting with " \
+ assert not as_attr, (
+ "No subprot supported for fields "
+ "to be serialized as attributes, use type casting with "
"customized serializers in the current protocol instead."
-
- self._enter_cloth(ctx, cloth, parent,
- method=cls_attrs.method, skip=as_data)
-
- ret = subprot.subserialize(ctx, cls, inst, parent, name,
- as_attr=as_attr, as_data=as_data, **kwargs)
+ )
+
+ self._enter_cloth(
+ ctx, cloth, parent, method=cls_attrs.method, skip=as_data
+ )
+
+ ret = subprot.subserialize(
+ ctx,
+ cls,
+ inst,
+ parent,
+ name,
+ as_attr=as_attr,
+ as_data=as_data,
+ **kwargs,
+ )
# if there is no subprotocol, try rendering the value
else:
@@ -593,20 +663,29 @@ def to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
attrs = {}
if as_attr:
# FIXME: test needed
- attrs[name] = ''
+ attrs[name] = ""
- self._enter_cloth(ctx, cloth, parent, attrib=attrs,
- method=cls_attrs.method)
+ self._enter_cloth(
+ ctx, cloth, parent, attrib=attrs, method=cls_attrs.method
+ )
identifier = "%s.%s" % (prot_name, "null_to_cloth")
- logger_s.debug("Writing '%s' using %s type: %s.", name,
- identifier, cls.get_type_name())
+ logger_s.debug(
+ "Writing '%s' using %s type: %s.",
+ name,
+ identifier,
+ cls.get_type_name(),
+ )
parent.write(cloth)
else:
- logger_s.debug("Skipping '%s' type: %s because empty.",
- name, cls.get_type_name())
- self._enter_cloth(ctx, cloth, parent, skip=True,
- method=cls_attrs.method)
+ logger_s.debug(
+ "Skipping '%s' type: %s because empty.",
+ name,
+ cls.get_type_name(),
+ )
+ self._enter_cloth(
+ ctx, cloth, parent, skip=True, method=cls_attrs.method
+ )
elif as_data:
# we only support XmlData of a primitive.,. is this a
@@ -621,8 +700,9 @@ def to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
sub_name = name
attrs = {sub_name: self.to_unicode(cls, inst)}
- self._enter_cloth(ctx, cloth, parent, attrib=attrs,
- method=cls_attrs.method)
+ self._enter_cloth(
+ ctx, cloth, parent, attrib=attrs, method=cls_attrs.method
+ )
else:
# push the instance at hand to instance stack. this makes it
@@ -634,8 +714,9 @@ def to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
# try rendering the array value
if not from_arr and cls.Attributes.max_occurs > 1:
- ret = self.array_to_cloth(ctx, cls, inst, cloth, parent,
- as_attr=as_attr, name=name)
+ ret = self.array_to_cloth(
+ ctx, cls, inst, cloth, parent, as_attr=as_attr, name=name
+ )
else:
# try rendering anything else
handler = self.rendering_handlers[cls]
@@ -647,13 +728,14 @@ def to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
# name, identifier, cls.get_type_name(),
# log_repr(inst, cls, from_array=from_arr))
- ret = handler(ctx, cls, inst, cloth, parent, name=name,
- as_attr=as_attr)
+ ret = handler(
+ ctx, cls, inst, cloth, parent, name=name, as_attr=as_attr
+ )
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
try:
@@ -662,8 +744,7 @@ def to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
pass
finally:
if pushed:
- logger_c.debug("%s %r popped %r %r", B("#"),
- self, cls, inst)
+ logger_c.debug("%s %r popped %r %r", B("#"), self, cls, inst)
ctx.outprot_ctx.inst_stack.pop()
else:
@@ -671,8 +752,7 @@ def to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
logger_c.debug("%s %r popped %r %r", B("#"), self, cls, inst)
ctx.outprot_ctx.inst_stack.pop()
- def model_base_to_cloth(self, ctx, cls, inst, cloth, parent, name,
- **kwargs):
+ def model_base_to_cloth(self, ctx, cls, inst, cloth, parent, name, **kwargs):
cls_attrs = self.get_cls_attrs(cls)
self._enter_cloth(ctx, cloth, parent, method=cls_attrs.method)
@@ -688,7 +768,7 @@ def model_base_to_cloth(self, ctx, cls, inst, cloth, parent, name,
def xml_to_cloth(self, ctx, cls, inst, cloth, parent, name, **_):
cls_attrs = self.get_cls_attrs(cls)
self._enter_cloth(ctx, cloth, parent, method=cls_attrs.method)
- if isinstance(inst, string_types):
+ if isinstance(inst, str):
inst = etree.fromstring(inst)
parent.write(inst)
@@ -700,7 +780,7 @@ def any_to_cloth(self, ctx, cls, inst, cloth, parent, name, **_):
def html_to_cloth(self, ctx, cls, inst, cloth, parent, name, **_):
cls_attrs = self.get_cls_attrs(cls)
self._enter_cloth(ctx, cloth, parent, method=cls_attrs.method)
- if isinstance(inst, string_types):
+ if isinstance(inst, str):
inst = html.fromstring(inst)
parent.write(inst)
@@ -710,8 +790,9 @@ def any_uri_to_cloth(self, ctx, cls, inst, cloth, parent, name, **kwargs):
self.any_uri_to_parent(ctx, cls, inst, parent, name, **kwargs)
@coroutine
- def complex_to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
- as_attr=False, **kwargs):
+ def complex_to_cloth(
+ self, ctx, cls, inst, cloth, parent, name=None, as_attr=False, **kwargs
+ ):
fti = cls.get_flat_type_info(cls)
cls_attrs = self.get_cls_attrs(cls)
@@ -720,8 +801,7 @@ def complex_to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
elt_check = set()
attrib = self._gen_attrib_dict(inst, fti)
- self._enter_cloth(ctx, cloth, parent, attrib=attrib,
- method=cls_attrs.method)
+ self._enter_cloth(ctx, cloth, parent, attrib=attrib, method=cls_attrs.method)
for elt in self._get_elts(cloth, self.MRPC_ID):
self._actions_to_cloth(ctx, cls, inst, elt)
@@ -736,13 +816,27 @@ def complex_to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
# Check for xmldata after entering the cloth.
as_data_field = cloth.attrib.get(self.DATA_ATTR_NAME, None)
if as_data_field is not None:
- self._process_field(ctx, cls, inst, parent, cloth, fti,
- as_data_field, as_attr, True, fti_check, elt_check, **kwargs)
+ self._process_field(
+ ctx,
+ cls,
+ inst,
+ parent,
+ cloth,
+ fti,
+ as_data_field,
+ as_attr,
+ True,
+ fti_check,
+ elt_check,
+ **kwargs,
+ )
for elt in elts:
- for k_attr, as_attr, as_data in ((self.ID_ATTR_NAME, False, False),
- (self.ATTR_ATTR_NAME, True, False),
- (self.DATA_ATTR_NAME, False, True)):
+ for k_attr, as_attr, as_data in (
+ (self.ID_ATTR_NAME, False, False),
+ (self.ATTR_ATTR_NAME, True, False),
+ (self.DATA_ATTR_NAME, False, True),
+ ):
field_name = elt.attrib.get(k_attr, None)
if field_name is None:
continue
@@ -750,14 +844,25 @@ def complex_to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
if elt.tag == self.DATA_TAG_NAME:
as_data = True
- ret = self._process_field(ctx, cls, inst, parent, elt, fti,
- field_name, as_attr=as_attr, as_data=as_data,
- fti_check=fti_check, elt_check=elt_check, **kwargs)
+ ret = self._process_field(
+ ctx,
+ cls,
+ inst,
+ parent,
+ elt,
+ fti,
+ field_name,
+ as_attr=as_attr,
+ as_data=as_data,
+ fti_check=fti_check,
+ elt_check=elt_check,
+ **kwargs,
+ )
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
try:
@@ -777,15 +882,30 @@ def complex_to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
break
if len(fti_check) > 0:
- logger_s.debug("No element found for the following fields: %r",
- list(fti_check.keys()))
+ logger_s.debug(
+ "No element found for the following fields: %r", list(fti_check.keys())
+ )
if len(elt_check) > 0:
- logger_s.debug("No field found for element the following "
- "elements: %r", list(elt_check))
-
- def _process_field(self, ctx, cls, inst, parent,
- elt, fti, field_name, as_attr, as_data, fti_check, elt_check,
- **kwargs):
+ logger_s.debug(
+ "No field found for element the following " "elements: %r",
+ list(elt_check),
+ )
+
+ def _process_field(
+ self,
+ ctx,
+ cls,
+ inst,
+ parent,
+ elt,
+ fti,
+ field_name,
+ as_attr,
+ as_data,
+ fti_check,
+ elt_check,
+ **kwargs,
+ ):
field_type = fti.get(field_name, None)
fti_check.pop(field_name, None)
@@ -797,8 +917,7 @@ def _process_field(self, ctx, cls, inst, parent,
cls_attrs = self.get_cls_attrs(field_type)
if cls_attrs.exc:
- logger_c.debug("Skipping elt id %r because "
- "it was excluded", field_name)
+ logger_c.debug("Skipping elt id %r because " "it was excluded", field_name)
return
sub_name = cls_attrs.sub_name
@@ -814,24 +933,34 @@ def _process_field(self, ctx, cls, inst, parent,
val = getattr(inst, field_name, None)
if as_data:
- self._enter_cloth(ctx, elt, parent, skip=True, skip_dupe=True,
- method=cls_attrs.method)
-
- return self.to_cloth(ctx, field_type, val, elt, parent,
- name=sub_name, as_attr=as_attr, as_data=as_data, **kwargs)
+ self._enter_cloth(
+ ctx, elt, parent, skip=True, skip_dupe=True, method=cls_attrs.method
+ )
+
+ return self.to_cloth(
+ ctx,
+ field_type,
+ val,
+ elt,
+ parent,
+ name=sub_name,
+ as_attr=as_attr,
+ as_data=as_data,
+ **kwargs,
+ )
@coroutine
- def array_to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
- **kwargs):
+ def array_to_cloth(self, ctx, cls, inst, cloth, parent, name=None, **kwargs):
if isinstance(inst, PushBase):
while True:
- sv = (yield)
- ret = self.to_cloth(ctx, cls, sv, cloth, parent,
- name=name, from_arr=True, **kwargs)
+ sv = yield
+ ret = self.to_cloth(
+ ctx, cls, sv, cloth, parent, name=name, from_arr=True, **kwargs
+ )
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
try:
@@ -845,12 +974,13 @@ def array_to_cloth(self, ctx, cls, inst, cloth, parent, name=None,
for sv in inst:
was_empty = False
- ret = self.to_cloth(ctx, cls, sv, cloth, parent,
- from_arr=True, name=name, **kwargs)
+ ret = self.to_cloth(
+ ctx, cls, sv, cloth, parent, from_arr=True, name=name, **kwargs
+ )
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
try:
diff --git a/spyne/protocol/cloth/to_parent.py b/spyne/protocol/cloth/to_parent.py
index 43092805f..b0298b60b 100644
--- a/spyne/protocol/cloth/to_parent.py
+++ b/spyne/protocol/cloth/to_parent.py
@@ -20,54 +20,75 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
+from collections.abc import Iterable
from inspect import isgenerator
-from spyne.util.six.moves.collections_abc import Iterable
from lxml import etree, html
from lxml.builder import E
-from spyne.const.xml import NS_XSI, NS_SOAP11_ENV, SOAP11_ENV
-from spyne.model import PushBase, ComplexModelBase, AnyXml, Fault, AnyDict, \
- AnyHtml, ModelBase, ByteArray, XmlData, Any, AnyUri, ImageUri, XmlAttribute
-
+from spyne.const.xml import NS_SOAP11_ENV, NS_XSI, SOAP11_ENV
+from spyne.model import (
+ Any,
+ AnyDict,
+ AnyHtml,
+ AnyUri,
+ AnyXml,
+ ByteArray,
+ ComplexModelBase,
+ Fault,
+ ImageUri,
+ ModelBase,
+ PushBase,
+ XmlAttribute,
+ XmlData,
+)
from spyne.model.enum import EnumBase
from spyne.protocol import OutProtocolBase
from spyne.protocol.xml import SchemaValidationError
-from spyne.util import coroutine, Break, six
+from spyne.util import Break, coroutine
from spyne.util.cdict import cdict
+from spyne.util.color import B, R
from spyne.util.etreeconv import dict_to_etree
-from spyne.util.color import R, B
-
-from spyne.util.six import string_types
class ToParentMixin(OutProtocolBase):
- def __init__(self, app=None, mime_type=None, ignore_uncap=False,
- ignore_wrappers=False, polymorphic=True):
- super(ToParentMixin, self).__init__(app=app, mime_type=mime_type,
- ignore_uncap=ignore_uncap, ignore_wrappers=ignore_wrappers)
+ def __init__(
+ self,
+ app=None,
+ mime_type=None,
+ ignore_uncap=False,
+ ignore_wrappers=False,
+ polymorphic=True,
+ ):
+ super(ToParentMixin, self).__init__(
+ app=app,
+ mime_type=mime_type,
+ ignore_uncap=ignore_uncap,
+ ignore_wrappers=ignore_wrappers,
+ )
self.polymorphic = polymorphic
self.use_global_null_handler = True
- self.serialization_handlers = cdict({
- ModelBase: self.model_base_to_parent,
-
- AnyXml: self.any_xml_to_parent,
- AnyUri: self.any_uri_to_parent,
- ImageUri: self.imageuri_to_parent,
- AnyDict: self.any_dict_to_parent,
- AnyHtml: self.any_html_to_parent,
- Any: self.any_to_parent,
-
- Fault: self.fault_to_parent,
- EnumBase: self.enum_to_parent,
- ByteArray: self.byte_array_to_parent,
- ComplexModelBase: self.complex_to_parent,
- SchemaValidationError: self.schema_validation_error_to_parent,
- })
+ self.serialization_handlers = cdict(
+ {
+ ModelBase: self.model_base_to_parent,
+ AnyXml: self.any_xml_to_parent,
+ AnyUri: self.any_uri_to_parent,
+ ImageUri: self.imageuri_to_parent,
+ AnyDict: self.any_dict_to_parent,
+ AnyHtml: self.any_html_to_parent,
+ Any: self.any_to_parent,
+ Fault: self.fault_to_parent,
+ EnumBase: self.enum_to_parent,
+ ByteArray: self.byte_array_to_parent,
+ ComplexModelBase: self.complex_to_parent,
+ SchemaValidationError: self.schema_validation_error_to_parent,
+ }
+ )
def start_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
"""This is what subserialize calls"""
@@ -81,8 +102,11 @@ def start_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
@staticmethod
def get_subprot(ctx, cls_attrs, nosubprot=False):
subprot = cls_attrs.prot
- if subprot is not None and not nosubprot and not \
- (subprot in ctx.protocol.prot_stack):
+ if (
+ subprot is not None
+ and not nosubprot
+ and not (subprot in ctx.protocol.prot_stack)
+ ):
return subprot
return None
@@ -109,12 +133,12 @@ def to_parent(self, ctx, cls, inst, parent, name, nosubprot=False, **kwargs):
subprot = self.get_subprot(ctx, cls_attrs, nosubprot)
if subprot is not None:
logger.debug("Subprot from %r to %r", self, subprot)
- ret = self.to_subprot(ctx, cls, inst, parent, name, subprot,
- **kwargs)
+ ret = self.to_subprot(ctx, cls, inst, parent, name, subprot, **kwargs)
else:
# if there is a class cloth, switch to it
- has_cloth, cor_handle = self.check_class_cloths(ctx, cls, inst,
- parent, name, **kwargs)
+ has_cloth, cor_handle = self.check_class_cloths(
+ ctx, cls, inst, parent, name, **kwargs
+ )
if has_cloth:
ret = cor_handle
@@ -131,9 +155,13 @@ def to_parent(self, ctx, cls, inst, parent, name, nosubprot=False, **kwargs):
# if instance is still None, use the global null handler to
# serialize it
if inst is None and self.use_global_null_handler:
- identifier = prot_name + '.null_to_parent'
- logger.debug("Writing %s using %s for %s.", name,
- identifier, cls.get_type_name())
+ identifier = prot_name + ".null_to_parent"
+ logger.debug(
+ "Writing %s using %s for %s.",
+ name,
+ identifier,
+ cls.get_type_name(),
+ )
self.null_to_parent(ctx, cls, inst, parent, name, **kwargs)
return
@@ -144,12 +172,11 @@ def to_parent(self, ctx, cls, inst, parent, name, nosubprot=False, **kwargs):
# if cls is an iterable of values and it's not being iterated
# on, do it
- from_arr = kwargs.get('from_arr', False)
+ from_arr = kwargs.get("from_arr", False)
# we need cls.Attributes here because we need the ACTUAL attrs
# that were set by the Array.__new__
if not from_arr and cls.Attributes.max_occurs > 1:
- ret = self.array_to_parent(ctx, cls, inst, parent, name,
- **kwargs)
+ ret = self.array_to_parent(ctx, cls, inst, parent, name, **kwargs)
else:
# fetch the serializer for the class at hand
try:
@@ -162,17 +189,20 @@ def to_parent(self, ctx, cls, inst, parent, name, nosubprot=False, **kwargs):
return # ignore it if requested
# raise the error otherwise
- logger.error("%r is missing handler for "
- "%r for field %r", self, cls, name)
+ logger.error(
+ "%r is missing handler for " "%r for field %r",
+ self,
+ cls,
+ name,
+ )
raise
# push the instance at hand to instance stack. this makes it
# easier for protocols to make decisions based on parents
# of instances at hand.
- ctx.outprot_ctx.inst_stack.append( (cls, inst, from_arr) )
+ ctx.outprot_ctx.inst_stack.append((cls, inst, from_arr))
pushed = True
- logger.debug("%s %r pushed %r using %r",
- R("$"), self, cls, handler)
+ logger.debug("%s %r pushed %r using %r", R("$"), self, cls, handler)
# disabled for performance reasons
# from spyne.util.web import log_repr
@@ -188,7 +218,7 @@ def to_parent(self, ctx, cls, inst, parent, name, nosubprot=False, **kwargs):
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
@@ -203,8 +233,7 @@ def to_parent(self, ctx, cls, inst, parent, name, nosubprot=False, **kwargs):
self._close_cloth(ctx, parent)
if pushed:
- logger.debug("%s %r popped %r %r", B("$"), self, cls,
- inst)
+ logger.debug("%s %r popped %r %r", B("$"), self, cls, inst)
ctx.outprot_ctx.inst_stack.pop()
else:
@@ -232,16 +261,17 @@ def array_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
try:
while True:
- sv = (yield)
+ sv = yield
# disabled because to_parent is supposed to take care of this
- #ctx.protocol.inst_stack.append((cls, sv, True))
- kwargs['from_arr'] = True
- kwargs['array_index'] = i
+ # ctx.protocol.inst_stack.append((cls, sv, True))
+ kwargs["from_arr"] = True
+ kwargs["array_index"] = i
if ser_subprot is not None:
- ser_subprot.column_table_before_row(ctx, cls, inst,
- parent, name, **kwargs)
+ ser_subprot.column_table_before_row(
+ ctx, cls, inst, parent, name, **kwargs
+ )
ret = self.to_parent(ctx, cls, sv, parent, name, **kwargs)
@@ -249,7 +279,7 @@ def array_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
@@ -260,43 +290,46 @@ def array_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
finally:
# disabled because to_parent is supposed to take care of this
- #popped_val = ctx.protocol.inst_stack.pop()
- #assert popped_val is sv
+ # popped_val = ctx.protocol.inst_stack.pop()
+ # assert popped_val is sv
if ser_subprot is not None:
- ser_subprot.column_table_before_row(ctx, cls,
- inst, parent, name, **kwargs)
+ ser_subprot.column_table_before_row(
+ ctx, cls, inst, parent, name, **kwargs
+ )
else:
# disabled because to_parent is supposed to take care of this
- #popped_val = ctx.protocol.inst_stack.pop()
- #assert popped_val is sv
+ # popped_val = ctx.protocol.inst_stack.pop()
+ # assert popped_val is sv
if ser_subprot is not None:
- ser_subprot.column_table_after_row(ctx, cls, inst,
- parent, name, **kwargs)
+ ser_subprot.column_table_after_row(
+ ctx, cls, inst, parent, name, **kwargs
+ )
except Break:
# pusher is done with pushing
pass
else:
- assert isinstance(inst, Iterable), ("%r is not iterable" % (inst,))
+ assert isinstance(inst, Iterable), "%r is not iterable" % (inst,)
for i, sv in enumerate(inst):
# disabled because to_parent is supposed to take care of this
- #ctx.protocol.inst_stack.append((cls, sv, True)
- kwargs['from_arr'] = True
- kwargs['array_index'] = i
+ # ctx.protocol.inst_stack.append((cls, sv, True)
+ kwargs["from_arr"] = True
+ kwargs["array_index"] = i
if ser_subprot is not None:
- ser_subprot.column_table_before_row(ctx, cls, inst, parent,
- name, **kwargs)
+ ser_subprot.column_table_before_row(
+ ctx, cls, inst, parent, name, **kwargs
+ )
ret = self.to_parent(ctx, cls, sv, parent, name, **kwargs)
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
@@ -307,21 +340,23 @@ def array_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
finally:
# disabled because to_parent is supposed to take care of this
- #popped_val = ctx.protocol.inst_stack.pop()
- #assert popped_val is sv
+ # popped_val = ctx.protocol.inst_stack.pop()
+ # assert popped_val is sv
if ser_subprot is not None:
- ser_subprot.column_table_after_row(ctx, cls, inst,
- parent, name, **kwargs)
+ ser_subprot.column_table_after_row(
+ ctx, cls, inst, parent, name, **kwargs
+ )
else:
# disabled because to_parent is supposed to take care of this
- #popped_val = ctx.protocol.inst_stack.pop()
- #assert popped_val is sv
+ # popped_val = ctx.protocol.inst_stack.pop()
+ # assert popped_val is sv
if ser_subprot is not None:
- ser_subprot.column_table_after_row(ctx, cls, inst,
- parent, name, **kwargs)
+ ser_subprot.column_table_after_row(
+ ctx, cls, inst, parent, name, **kwargs
+ )
def not_supported(self, ctx, cls, *args, **kwargs):
if not self.ignore_uncap:
@@ -340,19 +375,19 @@ def model_base_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
parent.write(E(name, self.to_unicode(cls, inst)))
def null_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
- parent.write(E(name, **{'{%s}nil' % NS_XSI: 'true'}))
+ parent.write(E(name, **{"{%s}nil" % NS_XSI: "true"}))
def enum_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
self.model_base_to_parent(ctx, cls, str(inst), parent, name)
def any_xml_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
- if isinstance(inst, string_types):
+ if isinstance(inst, str):
inst = etree.fromstring(inst)
parent.write(E(name, inst))
def any_html_to_unicode(self, cls, inst, **_):
- if isinstance(inst, (str, six.text_type)):
+ if isinstance(inst, str):
inst = html.fromstring(inst)
return inst
@@ -361,11 +396,11 @@ def any_html_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
cls_attrs = self.get_cls_attrs(cls)
if cls_attrs.as_string:
- if not (isinstance(inst, str) or isinstance(inst, six.text_type)):
+ if not isinstance(inst, str):
inst = html.tostring(inst)
else:
- if isinstance(inst, str) or isinstance(inst, six.text_type):
+ if isinstance(inst, str):
inst = html.fromstring(inst)
parent.write(E(name, inst))
@@ -432,12 +467,13 @@ def _write_members(self, ctx, cls, inst, parent, use_ns=None, **kwargs):
continue
if subvalue is not None or attr.min_occurs > 0:
- ret = self.to_parent(ctx, v, subvalue, parent, sub_name,
- use_ns=use_ns, **kwargs)
+ ret = self.to_parent(
+ ctx, v, subvalue, parent, sub_name, use_ns=use_ns, **kwargs
+ )
if ret is not None:
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as b:
try:
@@ -454,7 +490,7 @@ def _complex_to_parent_do(self, ctx, cls, inst, parent, **kwargs):
if ret is not None:
try:
while True:
- sv2 = (yield) # may throw Break
+ sv2 = yield # may throw Break
ret.send(sv2)
except Break:
@@ -463,27 +499,30 @@ def _complex_to_parent_do(self, ctx, cls, inst, parent, **kwargs):
except StopIteration:
pass
- def complex_to_parent(self, ctx, cls, inst, parent, name,
- from_arr=False, use_ns=None, **kwargs):
+ def complex_to_parent(
+ self, ctx, cls, inst, parent, name, from_arr=False, use_ns=None, **kwargs
+ ):
if not from_arr:
inst = cls.get_serialization_instance(inst)
attrib = self._gen_attrib_dict(inst, cls.get_flat_type_info(cls))
if self.skip_root_tag:
- self._complex_to_parent_do(ctx, cls, inst, parent,
- from_arr=from_arr, **kwargs)
+ self._complex_to_parent_do(
+ ctx, cls, inst, parent, from_arr=from_arr, **kwargs
+ )
else:
- if name is None or name == '':
- name = self._gen_sub_name(cls, self.get_cls_attrs(cls),
- cls.get_type_name(), use_ns)
- logger.debug("name is empty, long live name: %s, cls: %r",
- name, cls)
+ if name is None or name == "":
+ name = self._gen_sub_name(
+ cls, self.get_cls_attrs(cls), cls.get_type_name(), use_ns
+ )
+ logger.debug("name is empty, long live name: %s, cls: %r", name, cls)
with parent.element(name, attrib=attrib):
- self._complex_to_parent_do(ctx, cls, inst, parent,
- from_arr=from_arr, **kwargs)
+ self._complex_to_parent_do(
+ ctx, cls, inst, parent, from_arr=from_arr, **kwargs
+ )
def fault_to_parent(self, ctx, cls, inst, parent, name):
PREF_SOAP_ENV = ctx.app.interface.prefmap[NS_SOAP11_ENV]
@@ -491,7 +530,7 @@ def fault_to_parent(self, ctx, cls, inst, parent, name):
with parent.element(tag_name):
parent.write(
- E("faultcode", '%s:%s' % (PREF_SOAP_ENV, inst.faultcode)),
+ E("faultcode", "%s:%s" % (PREF_SOAP_ENV, inst.faultcode)),
E("faultstring", inst.faultstring),
E("faultactor", inst.faultactor),
)
@@ -510,7 +549,7 @@ def schema_validation_error_to_parent(self, ctx, cls, inst, parent, **_):
with parent.element(tag_name):
parent.write(
- E("faultcode", '%s:%s' % (PREF_SOAP_ENV, inst.faultcode)),
+ E("faultcode", "%s:%s" % (PREF_SOAP_ENV, inst.faultcode)),
# HACK: Does anyone know a better way of injecting raw xml entities?
E("faultstring", html.fromstring(inst.faultstring).text),
E("faultactor", inst.faultactor),
diff --git a/spyne/protocol/csv.py b/spyne/protocol/csv.py
index 915ca8814..1fc1786fc 100644
--- a/spyne/protocol/csv.py
+++ b/spyne/protocol/csv.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -27,26 +26,22 @@
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
import csv
+from io import StringIO
from spyne import ComplexModelBase
-from spyne.util import six
from spyne.protocol.dictdoc import HierDictDocument
-if six.PY2:
- from StringIO import StringIO
-else:
- from io import StringIO
-
def _complex_to_csv(prot, ctx):
- cls, = ctx.descriptor.out_message._type_info.values()
+ (cls,) = ctx.descriptor.out_message._type_info.values()
queue = StringIO()
- serializer, = cls._type_info.values()
+ (serializer,) = cls._type_info.values()
if issubclass(serializer, ComplexModelBase):
type_info = serializer.get_flat_type_info(serializer)
@@ -58,7 +53,7 @@ def _complex_to_csv(prot, ctx):
if ctx.out_error is not None:
writer = csv.writer(queue, dialect=csv.excel)
- writer.writerow(['Error in generating the document'])
+ writer.writerow(["Error in generating the document"])
if ctx.out_error is not None:
for r in ctx.out_error.to_bytes_iterable(ctx.out_error):
writer.writerow([r])
@@ -82,11 +77,6 @@ def _complex_to_csv(prot, ctx):
if ctx.out_object[0] is not None:
for v in ctx.out_object[0]:
d = prot._to_dict_value(serializer, v, set())
- if six.PY2:
- for k in d:
- if isinstance(d[k], unicode):
- d[k] = d[k].encode('utf8')
-
writer.writerow(d)
yval = queue.getvalue()
yield yval
@@ -94,20 +84,35 @@ def _complex_to_csv(prot, ctx):
class Csv(HierDictDocument):
- mime_type = 'text/csv'
+ mime_type = "text/csv"
text_based = True
type = set(HierDictDocument.type)
- type.add('csv')
-
- def __init__(self, app=None, validator=None, mime_type=None,
- ignore_uncap=False, ignore_wrappers=True, complex_as=dict,
- ordered=False, polymorphic=False, header=True):
-
- super(Csv, self).__init__(app=app, validator=validator,
- mime_type=mime_type, ignore_uncap=ignore_uncap,
- ignore_wrappers=ignore_wrappers, complex_as=complex_as,
- ordered=ordered, polymorphic=polymorphic)
+ type.add("csv")
+
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ mime_type=None,
+ ignore_uncap=False,
+ ignore_wrappers=True,
+ complex_as=dict,
+ ordered=False,
+ polymorphic=False,
+ header=True,
+ ):
+
+ super(Csv, self).__init__(
+ app=app,
+ validator=validator,
+ mime_type=mime_type,
+ ignore_uncap=ignore_uncap,
+ ignore_wrappers=ignore_wrappers,
+ complex_as=complex_as,
+ ordered=ordered,
+ polymorphic=polymorphic,
+ )
self.header = header
@@ -115,20 +120,22 @@ def create_in_document(self, ctx):
raise NotImplementedError()
def serialize(self, ctx, message):
- assert message in (self.RESPONSE, )
+ assert message in (self.RESPONSE,)
if ctx.out_object is None:
ctx.out_object = []
- assert len(ctx.descriptor.out_message._type_info) == 1, \
- "CSV Serializer supports functions with exactly one return type: " \
+ assert len(ctx.descriptor.out_message._type_info) == 1, (
+ "CSV Serializer supports functions with exactly one return type: "
"%r" % ctx.descriptor.out_message._type_info
+ )
def create_out_string(self, ctx):
ctx.out_string = _complex_to_csv(self, ctx)
- if 'http' in ctx.transport.type:
- ctx.transport.resp_headers['Content-Disposition'] = (
- 'attachment; filename=%s.csv;' % ctx.descriptor.name)
+ if "http" in ctx.transport.type:
+ ctx.transport.resp_headers["Content-Disposition"] = (
+ "attachment; filename=%s.csv;" % ctx.descriptor.name
+ )
def any_uri_to_unicode(self, cls, value, **_):
if isinstance(value, cls.Value):
diff --git a/spyne/protocol/dictdoc/__init__.py b/spyne/protocol/dictdoc/__init__.py
index c0cee4d71..26e3e38bc 100644
--- a/spyne/protocol/dictdoc/__init__.py
+++ b/spyne/protocol/dictdoc/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
diff --git a/spyne/protocol/dictdoc/_base.py b/spyne/protocol/dictdoc/_base.py
index a10b121a4..f3a73d407 100644
--- a/spyne/protocol/dictdoc/_base.py
+++ b/spyne/protocol/dictdoc/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,16 +17,25 @@
#
import logging
+
logger = logging.getLogger(__name__)
import re
+
RE_HTTP_ARRAY_INDEX = re.compile("\\[([0-9]+)\\]")
from spyne.error import ValidationError
-
-from spyne.model import Fault, Array, AnyXml, AnyHtml, Uuid, DateTime, Date, \
- Time, Duration
-
+from spyne.model import (
+ AnyHtml,
+ AnyXml,
+ Array,
+ Date,
+ DateTime,
+ Duration,
+ Fault,
+ Time,
+ Uuid,
+)
from spyne.protocol import ProtocolBase
@@ -44,22 +52,31 @@ class DictDocument(ProtocolBase):
_huge_numbers_as_string = False
text_based = False
- def __init__(self, app=None, validator=None, mime_type=None,
- ignore_uncap=False, ignore_wrappers=True, complex_as=dict,
- ordered=False, polymorphic=False, key_encoding=None):
-
- super(DictDocument, self).__init__(app, validator, mime_type,
- ignore_uncap, ignore_wrappers)
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ mime_type=None,
+ ignore_uncap=False,
+ ignore_wrappers=True,
+ complex_as=dict,
+ ordered=False,
+ polymorphic=False,
+ key_encoding=None,
+ ):
+
+ super(DictDocument, self).__init__(
+ app, validator, mime_type, ignore_uncap, ignore_wrappers
+ )
self.key_encoding = key_encoding
self.polymorphic = polymorphic
self.complex_as = complex_as
self.ordered = ordered
if ordered:
- raise NotImplementedError('ordered=True')
+ raise NotImplementedError("ordered=True")
- self.stringified_types = (DateTime, Date, Time, Uuid, Duration,
- AnyXml, AnyHtml)
+ self.stringified_types = (DateTime, Date, Time, Uuid, Duration, AnyXml, AnyHtml)
def set_validator(self, validator):
"""Sets the validator for the protocol.
@@ -67,7 +84,7 @@ def set_validator(self, validator):
:param validator: one of ('soft', None)
"""
- if validator == 'soft' or validator is self.SOFT_VALIDATION:
+ if validator == "soft" or validator is self.SOFT_VALIDATION:
self.validator = self.SOFT_VALIDATION
elif validator is None:
self.validator = None
@@ -82,7 +99,7 @@ def decompose_incoming_envelope(self, ctx, message):
assert message in (ProtocolBase.REQUEST, ProtocolBase.RESPONSE)
# set ctx.in_header
- ctx.transport.in_header_doc = None # use an rpc protocol if you want headers.
+ ctx.transport.in_header_doc = None # use an rpc protocol if you want headers.
doc = ctx.in_document
@@ -90,12 +107,13 @@ def decompose_incoming_envelope(self, ctx, message):
ctx.in_body_doc = doc
if message is ProtocolBase.REQUEST:
- #logger.debug('\theader : %r', ctx.in_header_doc)
- #logger.debug('\tbody : %r', ctx.in_body_doc)
+ # logger.debug('\theader : %r', ctx.in_header_doc)
+ # logger.debug('\tbody : %r', ctx.in_body_doc)
if not isinstance(doc, dict) or len(doc) != 1:
- raise ValidationError(doc,
- "Need a dictionary with exactly one key as method name.")
+ raise ValidationError(
+ doc, "Need a dictionary with exactly one key as method name."
+ )
if len(doc) == 0:
raise Fault("Client", "Empty request")
@@ -108,8 +126,8 @@ def gen_method_request_string(self, ctx):
Returns a string in the form of "{namespaces}method name".
"""
- mrs, = ctx.in_body_doc.keys()
- return '{%s}%s' % (self.app.interface.get_tns(), mrs)
+ (mrs,) = ctx.in_body_doc.keys()
+ return "{%s}%s" % (self.app.interface.get_tns(), mrs)
def deserialize(self, ctx, message):
raise NotImplementedError()
@@ -120,7 +138,7 @@ def serialize(self, ctx, message):
def create_in_document(self, ctx, in_string_encoding=None):
raise NotImplementedError()
- def create_out_string(self, ctx, out_string_encoding='utf8'):
+ def create_out_string(self, ctx, out_string_encoding="utf8"):
raise NotImplementedError()
def _check_freq_dict(self, cls, d, fti=None):
@@ -134,14 +152,18 @@ def _check_freq_dict(self, cls, d, fti=None):
min_o, max_o = attrs.min_occurs, attrs.max_occurs
if issubclass(v, Array) and v.Attributes.max_occurs == 1:
- v, = v._type_info.values()
+ (v,) = v._type_info.values()
attrs = self.get_cls_attrs(v)
min_o, max_o = attrs.min_occurs, attrs.max_occurs
if val < min_o:
- raise ValidationError("%r.%s" % (cls, k),
- '%%s member must occur at least %d times.' % min_o)
+ raise ValidationError(
+ "%r.%s" % (cls, k),
+ "%%s member must occur at least %d times." % min_o,
+ )
elif val > max_o:
- raise ValidationError("%r.%s" % (cls, k),
- '%%s member must occur at most %d times.' % max_o)
+ raise ValidationError(
+ "%r.%s" % (cls, k),
+ "%%s member must occur at most %d times." % max_o,
+ )
diff --git a/spyne/protocol/dictdoc/hier.py b/spyne/protocol/dictdoc/hier.py
index 1fdf2eacf..7feb4b383 100644
--- a/spyne/protocol/dictdoc/hier.py
+++ b/spyne/protocol/dictdoc/hier.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -20,23 +19,29 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
import re
+
RE_HTTP_ARRAY_INDEX = re.compile("\\[([0-9]+)\\]")
-from mmap import mmap
from collections import defaultdict
+from collections.abc import Iterable as AbcIterable
+from mmap import mmap
-from spyne.util import six
-from spyne.util.six.moves.collections_abc import Iterable as AbcIterable
-
-from spyne.error import ValidationError
-from spyne.error import ResourceNotFoundError
-
-from spyne.model import ByteArray, File, Fault, ComplexModelBase, Array, Any, \
- AnyDict, Uuid, Unicode
-
+from spyne.error import ResourceNotFoundError, ValidationError
+from spyne.model import (
+ Any,
+ AnyDict,
+ Array,
+ ByteArray,
+ ComplexModelBase,
+ Fault,
+ File,
+ Unicode,
+ Uuid,
+)
from spyne.protocol.dictdoc import DictDocument
@@ -47,17 +52,21 @@ class HierDictDocument(DictDocument):
Implement ``create_in_document()`` and ``create_out_string()`` to use this.
"""
- VALID_UNICODE_SOURCES = (six.text_type, six.binary_type, memoryview,
- mmap, bytearray)
+ VALID_UNICODE_SOURCES = (
+ str,
+ bytes,
+ memoryview,
+ mmap,
+ bytearray,
+ )
from_serstr = DictDocument.from_unicode
to_serstr = DictDocument.to_unicode
def get_class_name(self, cls):
class_name = cls.get_type_name()
- if not six.PY2:
- if isinstance(class_name, bytes):
- class_name = class_name.decode('utf8')
+ if isinstance(class_name, bytes):
+ class_name = class_name.decode("utf8")
return class_name
@@ -69,7 +78,7 @@ def get_complex_as(self, attr):
def deserialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_deserialize', ctx)
+ self.event_manager.fire_event("before_deserialize", ctx)
if ctx.descriptor is None:
raise ResourceNotFoundError(ctx.method_request_string)
@@ -92,14 +101,13 @@ def deserialize(self, ctx, message):
if self.ignore_wrappers:
doc = doc.get(class_name, None)
- result_message = self._doc_to_object(ctx, body_class, doc,
- self.validator)
+ result_message = self._doc_to_object(ctx, body_class, doc, self.validator)
ctx.in_object = result_message
else:
ctx.in_object = []
- self.event_manager.fire_event('after_deserialize', ctx)
+ self.event_manager.fire_event("after_deserialize", ctx)
def _fault_to_doc(self, inst, cls=None):
if cls is None:
@@ -118,7 +126,7 @@ def _fault_to_doc(self, inst, cls=None):
def serialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_serialize', ctx)
+ self.event_manager.fire_event("before_serialize", ctx)
if ctx.out_error is not None:
ctx.out_document = self._fault_to_doc(ctx.out_error)
@@ -139,7 +147,7 @@ def serialize(self, ctx, message):
# assign raw result to its wrapper, result_message
if ctx.descriptor.is_out_bare():
- out_instance, = ctx.out_object
+ (out_instance,) = ctx.out_object
else:
out_type_info = out_type.get_flat_type_info(out_type)
@@ -151,17 +159,18 @@ def serialize(self, ctx, message):
attrs = self.get_cls_attrs(v)
out_instance._safe_set(k, ctx.out_object[i], v, attrs)
- ctx.out_document = self._object_to_doc(out_type, out_instance, set()),
+ ctx.out_document = (self._object_to_doc(out_type, out_instance, set()),)
logger.debug("Response: %r", ctx.out_document)
- self.event_manager.fire_event('after_serialize', ctx)
+ self.event_manager.fire_event("after_serialize", ctx)
def validate(self, key, cls, inst):
if inst is None and self.get_cls_attrs(cls).nullable:
pass
- elif issubclass(cls, Unicode) and not isinstance(inst,
- self.VALID_UNICODE_SOURCES):
+ elif issubclass(cls, Unicode) and not isinstance(
+ inst, self.VALID_UNICODE_SOURCES
+ ):
raise ValidationError([key, inst])
def _from_dict_value(self, ctx, key, cls, inst, validator):
@@ -195,12 +204,14 @@ def _from_dict_value(self, ctx, key, cls, inst, validator):
retval = self._doc_to_object(ctx, cls, inst, validator)
else:
- if cls_attrs.empty_is_none and inst in (u'', b''):
+ if cls_attrs.empty_is_none and inst in ("", b""):
inst = None
- if (validator is self.SOFT_VALIDATION
- and isinstance(inst, six.string_types)
- and not cls.validate_string(cls, inst)):
+ if (
+ validator is self.SOFT_VALIDATION
+ and isinstance(inst, str)
+ and not cls.validate_string(cls, inst)
+ ):
raise ValidationError([key, inst])
if issubclass(cls, (ByteArray, Uuid)):
@@ -208,24 +219,28 @@ def _from_dict_value(self, ctx, key, cls, inst, validator):
elif issubclass(cls, Unicode):
if isinstance(inst, bytearray):
- retval = six.text_type(inst,
- encoding=cls_attrs.encoding or 'ascii',
- errors=cls_attrs.unicode_errors)
+ retval = str(
+ inst,
+ encoding=cls_attrs.encoding or "ascii",
+ errors=cls_attrs.unicode_errors,
+ )
elif isinstance(inst, memoryview):
# FIXME: memoryview needs a .decode() function to avoid
# needless copying here
retval = inst.tobytes().decode(
- cls_attrs.encoding or 'ascii',
- errors=cls_attrs.unicode_errors)
+ cls_attrs.encoding or "ascii",
+ errors=cls_attrs.unicode_errors,
+ )
elif isinstance(inst, mmap):
# FIXME: mmap needs a .decode() function to avoid
# needless copying here
- retval = mmap[:].decode(cls_attrs.encoding,
- errors=cls_attrs.unicode_errors)
+ retval = mmap[:].decode(
+ cls_attrs.encoding, errors=cls_attrs.unicode_errors
+ )
- elif isinstance(inst, six.binary_type):
+ elif isinstance(inst, bytes):
retval = self.unicode_from_bytes(cls, inst)
else:
@@ -258,8 +273,9 @@ def _doc_to_object(self, ctx, cls, doc, validator=None):
raise ValidationError(doc)
for i, child in enumerate(doc):
- retval.append(self._from_dict_value(ctx, i, serializer, child,
- validator))
+ retval.append(
+ self._from_dict_value(ctx, i, serializer, child, validator)
+ )
return retval
@@ -272,28 +288,35 @@ def _doc_to_object(self, ctx, cls, doc, validator=None):
return None
if len(doc) > 1:
- raise ValidationError(doc, "There can be only one entry in a "
- "wrapper dict")
+ raise ValidationError(
+ doc, "There can be only one entry in a " "wrapper dict"
+ )
subclasses = cls.get_subclasses()
- (class_name, doc), = doc.items()
- if not six.PY2 and isinstance(class_name, bytes):
- class_name = class_name.decode('utf8')
+ ((class_name, doc),) = doc.items()
+ if isinstance(class_name, bytes):
+ class_name = class_name.decode("utf8")
- if cls.get_type_name() != class_name and subclasses is not None \
- and len(subclasses) > 0:
+ if (
+ cls.get_type_name() != class_name
+ and subclasses is not None
+ and len(subclasses) > 0
+ ):
for subcls in subclasses:
if subcls.get_type_name() == class_name:
break
else:
- raise ValidationError(class_name,
- "Class name %%r is not registered as a subclass of %r" %
- cls.get_type_name())
+ raise ValidationError(
+ class_name,
+ "Class name %%r is not registered as a subclass of %r"
+ % cls.get_type_name(),
+ )
if not self.issubclass(subcls, cls):
- raise ValidationError(class_name,
- "Class name %%r is not a subclass of %r" %
- cls.get_type_name())
+ raise ValidationError(
+ class_name,
+ "Class name %%r is not a subclass of %r" % cls.get_type_name(),
+ )
cls = subcls
inst = cls.get_deserialization_instance(ctx)
@@ -315,8 +338,14 @@ def _doc_to_object(self, ctx, cls, doc, validator=None):
# with the incoming sequence with field names.
# TODO: cache this
try:
- items = zip([k for k, v in flat_type_info.items()
- if not self.get_cls_attrs(v).exc], doc)
+ items = zip(
+ [
+ k
+ for k, v in flat_type_info.items()
+ if not self.get_cls_attrs(v).exc
+ ],
+ doc,
+ )
except TypeError as e:
logger.error("Invalid document %r for %r", doc, cls)
raise ValidationError(doc)
@@ -347,8 +376,7 @@ def _doc_to_object(self, ctx, cls, doc, validator=None):
subinst = []
for a in v:
- subinst.append(
- self._from_dict_value(ctx, k, member, a, validator))
+ subinst.append(self._from_dict_value(ctx, k, member, a, validator))
else:
subinst = self._from_dict_value(ctx, k, member, v, validator)
@@ -400,16 +428,16 @@ def _object_to_doc(self, cls, inst, tags=None):
# cls_attrs = self.get_cls_attrs(cls)
if self.ignore_wrappers:
- ti = getattr(cls, '_type_info', {})
+ ti = getattr(cls, "_type_info", {})
while cls.Attributes._wrapper and len(ti) == 1:
# Wrappers are auto-generated objects that have exactly one
# child type.
- key, = ti.keys()
+ (key,) = ti.keys()
if not issubclass(cls, Array):
inst = getattr(inst, key, None)
- cls, = ti.values()
- ti = getattr(cls, '_type_info', {})
+ (cls,) = ti.values()
+ ti = getattr(cls, "_type_info", {})
# transform the results into a dict:
if cls.Attributes.max_occurs > 1:
@@ -420,27 +448,31 @@ def _object_to_doc(self, cls, inst, tags=None):
if id(subinst) in tags:
# even when there is ONE already-serialized instance,
# we throw the whole thing away.
- logger.debug("Throwing the whole array away because "
- "found %d", id(subinst))
+ logger.debug(
+ "Throwing the whole array away because " "found %d",
+ id(subinst),
+ )
# this is DANGEROUS
- #logger.debug("Said array: %r", inst)
+ # logger.debug("Said array: %r", inst)
return None
- retval.append(self._to_dict_value(cls, subinst, tags,
- cls_orig=cls_orig or cls))
+ retval.append(
+ self._to_dict_value(
+ cls, subinst, tags, cls_orig=cls_orig or cls
+ )
+ )
else:
- retval = self._to_dict_value(cls, inst, tags,
- cls_orig=cls_orig or cls)
+ retval = self._to_dict_value(cls, inst, tags, cls_orig=cls_orig or cls)
return retval
def _get_member_pairs(self, cls, inst, tags):
old_len = len(tags)
tags = tags | {id(inst)}
- assert len(tags) > old_len, ("Offending instance: %r" % inst)
+ assert len(tags) > old_len, "Offending instance: %r" % inst
for k, v in self.sort_fields(cls):
subattr = self.get_cls_attrs(v)
@@ -500,7 +532,7 @@ def _to_dict_value(self, cls, inst, tags, cls_orig=None):
return inst
if issubclass(cls, Array):
- st, = cls._type_info.values()
+ (st,) = cls._type_info.values()
return self._object_to_doc(st, inst, tags)
if issubclass(cls, ComplexModelBase):
@@ -520,15 +552,18 @@ def _complex_to_doc(self, cls, inst, tags):
subinst = getattr(inst, sf, None)
- logger.debug("Render complex object %s to the value %r of its "
- "field '%s'", cls.get_type_name(), subinst, sf)
+ logger.debug(
+ "Render complex object %s to the value %r of its " "field '%s'",
+ cls.get_type_name(),
+ subinst,
+ sf,
+ )
return self.to_unicode(subcls, subinst)
cls_attr = self.get_cls_attrs(cls)
complex_as = self.get_complex_as(cls_attr)
- if complex_as is list or \
- getattr(cls.Attributes, 'serialize_as', False) is list:
+ if complex_as is list or getattr(cls.Attributes, "serialize_as", False) is list:
return list(self._complex_to_list(cls, inst, tags))
return self._complex_to_dict(cls, inst, tags)
@@ -540,28 +575,31 @@ def _complex_to_dict(self, cls, inst, tags):
if self.key_encoding is None:
d = complex_as(self._get_member_pairs(cls, inst, tags))
- if (self.ignore_wrappers or cls_attr.not_wrapped) \
- and not bool(cls_attr.wrapper):
+ if (self.ignore_wrappers or cls_attr.not_wrapped) and not bool(
+ cls_attr.wrapper
+ ):
return d
else:
- if isinstance(cls_attr.wrapper,
- (six.text_type, six.binary_type)):
+ if isinstance(cls_attr.wrapper, (str, bytes)):
return {cls_attr.wrapper: d}
else:
return {cls.get_type_name(): d}
else:
- d = complex_as( (k.encode(self.key_encoding), v) for k, v in
- self._get_member_pairs(cls, inst, tags) )
-
- if (self.ignore_wrappers or cls_attr.not_wrapped) \
- and not bool(cls_attr.wrapper):
+ d = complex_as(
+ (k.encode(self.key_encoding), v)
+ for k, v in self._get_member_pairs(cls, inst, tags)
+ )
+
+ if (self.ignore_wrappers or cls_attr.not_wrapped) and not bool(
+ cls_attr.wrapper
+ ):
return d
else:
- if isinstance(cls_attr.wrapper, six.text_type):
+ if isinstance(cls_attr.wrapper, str):
return {cls_attr.wrapper.encode(self.key_encoding): d}
- elif isinstance(cls_attr.wrapper, six.binary_type):
+ elif isinstance(cls_attr.wrapper, bytes):
return {cls_attr.wrapper: d}
else:
return {cls.get_type_name().encode(self.key_encoding): d}
diff --git a/spyne/protocol/dictdoc/simple.py b/spyne/protocol/dictdoc/simple.py
index 01d58dafb..0d31ef252 100644
--- a/spyne/protocol/dictdoc/simple.py
+++ b/spyne/protocol/dictdoc/simple.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,22 +17,26 @@
#
import logging
+
logger = logging.getLogger(__name__)
import re
+from collections import defaultdict, deque
-from collections import deque
-from collections import defaultdict
-
-from spyne.util import six
from spyne.error import ValidationError
-
-from spyne.model import ByteArray, String, File, ComplexModelBase, Array, \
- SimpleModel, Any, AnyDict, Unicode
-
+from spyne.model import (
+ Any,
+ AnyDict,
+ Array,
+ ByteArray,
+ ComplexModelBase,
+ File,
+ SimpleModel,
+ String,
+ Unicode,
+)
from spyne.protocol.dictdoc import DictDocument
-
RE_HTTP_ARRAY_INDEX = re.compile(r"\[([0-9]+)]")
@@ -81,13 +84,27 @@ class SimpleDictDocument(DictDocument):
flat dictionaries. The only example as of now is Http.
"""
- def __init__(self, app=None, validator=None, mime_type=None,
- ignore_uncap=False, ignore_wrappers=True, complex_as=dict,
- ordered=False, hier_delim='.', strict_arrays=False):
- super(SimpleDictDocument, self).__init__(app=app, validator=validator,
- mime_type=mime_type, ignore_uncap=ignore_uncap,
- ignore_wrappers=ignore_wrappers, complex_as=complex_as,
- ordered=ordered)
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ mime_type=None,
+ ignore_uncap=False,
+ ignore_wrappers=True,
+ complex_as=dict,
+ ordered=False,
+ hier_delim=".",
+ strict_arrays=False,
+ ):
+ super(SimpleDictDocument, self).__init__(
+ app=app,
+ validator=validator,
+ mime_type=mime_type,
+ ignore_uncap=ignore_uncap,
+ ignore_wrappers=ignore_wrappers,
+ complex_as=complex_as,
+ ordered=ordered,
+ )
self.hier_delim = hier_delim
self.strict_arrays = strict_arrays
@@ -98,10 +115,13 @@ def _to_native_values(self, cls, member, orig_k, k, v, req_enc, validator):
for v2 in v:
# some wsgi implementations pass unicode strings, some pass str
# strings. we get unicode here when we can and should.
- if v2 is not None and req_enc is not None \
- and not issubclass(member.type, String) \
- and issubclass(member.type, Unicode) \
- and not isinstance(v2, six.text_type):
+ if (
+ v2 is not None
+ and req_enc is not None
+ and not issubclass(member.type, String)
+ and issubclass(member.type, Unicode)
+ and not isinstance(v2, str)
+ ):
try:
v2 = v2.decode(req_enc)
except UnicodeDecodeError as e:
@@ -109,8 +129,10 @@ def _to_native_values(self, cls, member, orig_k, k, v, req_enc, validator):
# validate raw data (before deserialization)
try:
- if (validator is self.SOFT_VALIDATION and not
- member.type.validate_string(member.type, v2)):
+ if (
+ validator is self.SOFT_VALIDATION
+ and not member.type.validate_string(member.type, v2)
+ ):
raise ValidationError([orig_k, v2])
except TypeError:
@@ -124,19 +146,18 @@ def _to_native_values(self, cls, member, orig_k, k, v, req_enc, validator):
if isinstance(v2, File.Value):
native_v2 = v2
else:
- native_v2 = self.from_unicode(member.type, v2,
- self.binary_encoding)
+ native_v2 = self.from_unicode(member.type, v2, self.binary_encoding)
elif issubclass(member.type, ByteArray):
- native_v2 = self.from_unicode(member.type, v2,
- self.binary_encoding)
+ native_v2 = self.from_unicode(member.type, v2, self.binary_encoding)
else:
try:
native_v2 = self.from_unicode(member.type, v2)
except ValidationError as e:
ns = "%s.%s" % (cls.get_namespace(), cls.get_type_name())
- raise ValidationError(e.faultstring,
- "Validation failed for %s.%s: %%s" % (ns, k))
+ raise ValidationError(
+ e.faultstring, "Validation failed for %s.%s: %%s" % (ns, k)
+ )
# validate native data (after deserialization)
native_v2 = self._sanitize(cls_attrs, native_v2)
@@ -158,10 +179,12 @@ def simple_dict_to_object(self, ctx, doc, cls, validator=None, req_enc=None):
return doc
if not issubclass(cls, ComplexModelBase):
- raise NotImplementedError("Interestingly, deserializing non complex"
- " types is not yet implemented. You can"
- " use a ComplexModel to wrap that field."
- " Otherwise, patches are welcome.")
+ raise NotImplementedError(
+ "Interestingly, deserializing non complex"
+ " types is not yet implemented. You can"
+ " use a ComplexModel to wrap that field."
+ " Otherwise, patches are welcome."
+ )
# this is for validating cls.Attributes.{min,max}_occurs
frequencies = defaultdict(lambda: defaultdict(int))
@@ -174,8 +197,9 @@ def simple_dict_to_object(self, ctx, doc, cls, validator=None, req_enc=None):
else:
retval = cls.get_deserialization_instance(ctx)
- simple_type_info = cls.get_simple_type_info_with_prot(cls, self,
- hier_delim=self.hier_delim)
+ simple_type_info = cls.get_simple_type_info_with_prot(
+ cls, self, hier_delim=self.hier_delim
+ )
logger.debug("Simple type info key: %r", simple_type_info.keys())
@@ -189,7 +213,7 @@ def simple_dict_to_object(self, ctx, doc, cls, validator=None, req_enc=None):
continue
if member.can_be_empty:
- if v != ['empty']: # maybe raise a ValidationError instead?
+ if v != ["empty"]: # maybe raise a ValidationError instead?
# 'empty' is the only valid value at this point after all
continue
@@ -208,9 +232,9 @@ def simple_dict_to_object(self, ctx, doc, cls, validator=None, req_enc=None):
else:
# extract native values from the list of strings in the flat dict
# entries.
- value = self._to_native_values(cls, member, orig_k, k, v,
- req_enc, validator)
-
+ value = self._to_native_values(
+ cls, member, orig_k, k, v, req_enc, validator
+ )
# assign the native value to the relevant class in the nested object
# structure.
@@ -230,7 +254,7 @@ def simple_dict_to_object(self, ctx, doc, cls, validator=None, req_enc=None):
ncls, ninst = ctype_info[pkey], getattr(cinst, pkey, None)
nattrs = self.get_cls_attrs(ncls)
if issubclass(ncls, Array):
- ncls, = ncls._type_info.values()
+ (ncls,) = ncls._type_info.values()
ncls_attrs = self.get_cls_attrs(ncls)
mo = ncls_attrs.max_occurs
@@ -251,8 +275,9 @@ def simple_dict_to_object(self, ctx, doc, cls, validator=None, req_enc=None):
frequencies[cfreq_key][pkey] += 1
if nidx > len(ninst):
- raise ValidationError(orig_k,
- "%%r Invalid array index %d." % idx)
+ raise ValidationError(
+ orig_k, "%%r Invalid array index %d." % idx
+ )
if nidx == len(ninst):
ninst.append(ncls.get_deserialization_instance(ctx))
frequencies[cfreq_key][pkey] += 1
@@ -290,22 +315,26 @@ def simple_dict_to_object(self, ctx, doc, cls, validator=None, req_enc=None):
_v = getattr(cinst, member.path[-1], None)
is_set = True
if _v is None:
- is_set = cinst._safe_set(member.path[-1], value,
- member.type, member_attrs)
+ is_set = cinst._safe_set(
+ member.path[-1], value, member.type, member_attrs
+ )
else:
_v.extend(value)
- set_skip = 'set ' if is_set else 'SKIP'
- logger.debug("\t%s arr %r(%r) = %r" %
- (set_skip, member.path, pkey, value))
+ set_skip = "set " if is_set else "SKIP"
+ logger.debug(
+ "\t%s arr %r(%r) = %r" % (set_skip, member.path, pkey, value)
+ )
else:
- is_set = cinst._safe_set(member.path[-1], value[0],
- member.type, member_attrs)
+ is_set = cinst._safe_set(
+ member.path[-1], value[0], member.type, member_attrs
+ )
- set_skip = 'set ' if is_set else 'SKIP'
- logger.debug("\t%s val %r(%r) = %r" %
- (set_skip, member.path, pkey, value[0]))
+ set_skip = "set " if is_set else "SKIP"
+ logger.debug(
+ "\t%s val %r(%r) = %r" % (set_skip, member.path, pkey, value[0])
+ )
if validator is self.SOFT_VALIDATION:
logger.debug("\tvalidate_freq: \n%r", frequencies)
@@ -313,7 +342,7 @@ def simple_dict_to_object(self, ctx, doc, cls, validator=None, req_enc=None):
for i, path_cls in enumerate(k[:-1:2]):
attrs = self.get_cls_attrs(path_cls)
if not attrs.validate_freq:
- logger.debug("\t\tskip validate_freq: %r", k[:i*2])
+ logger.debug("\t\tskip validate_freq: %r", k[: i * 2])
break
else:
path_cls = k[-2]
@@ -322,13 +351,20 @@ def simple_dict_to_object(self, ctx, doc, cls, validator=None, req_enc=None):
if issubclass(cls, Array):
# unwrap the request object
- array_name, = cls._type_info.keys()
+ (array_name,) = cls._type_info.keys()
retval = getattr(retval, array_name)
return retval
- def object_to_simple_dict(self, cls, inst, retval=None,
- prefix=None, subinst_eater=lambda prot, v, t: v, tags=None):
+ def object_to_simple_dict(
+ self,
+ cls,
+ inst,
+ retval=None,
+ prefix=None,
+ subinst_eater=lambda prot, v, t: v,
+ tags=None,
+ ):
"""Converts a native python object to a flat dict.
See :func:`spyne.model.complex.ComplexModelBase.get_flat_type_info`.
@@ -361,10 +397,11 @@ def object_to_simple_dict(self, cls, inst, retval=None,
new_prefix.append(sub_name)
subinst = getattr(inst, k, None)
- if (issubclass(v, Array) or v.Attributes.max_occurs > 1) and \
- subinst is not None:
+ if (
+ issubclass(v, Array) or v.Attributes.max_occurs > 1
+ ) and subinst is not None:
if issubclass(v, Array):
- subtype, = v._type_info.values()
+ (subtype,) = v._type_info.values()
else:
subtype = v
@@ -382,25 +419,37 @@ def object_to_simple_dict(self, cls, inst, retval=None,
last_prefix = new_prefix[-1]
i = -1
for i, ssv in enumerate(subinst):
- new_prefix[-1] = '%s[%d]' % (last_prefix, i)
- self.object_to_simple_dict(subtype, ssv,
- retval, new_prefix,
- subinst_eater=subinst_eater, tags=tags)
+ new_prefix[-1] = "%s[%d]" % (last_prefix, i)
+ self.object_to_simple_dict(
+ subtype,
+ ssv,
+ retval,
+ new_prefix,
+ subinst_eater=subinst_eater,
+ tags=tags,
+ )
if i == -1:
key = self.hier_delim.join(new_prefix)
- retval[key] = 'empty'
+ retval[key] = "empty"
else:
- self.object_to_simple_dict(v, subinst, retval, new_prefix,
- subinst_eater=subinst_eater, tags=tags)
+ self.object_to_simple_dict(
+ v,
+ subinst,
+ retval,
+ new_prefix,
+ subinst_eater=subinst_eater,
+ tags=tags,
+ )
else:
key = self.hier_delim.join(prefix)
if key in retval:
- raise ValueError("%r.%s conflicts with previous value %r" %
- (cls, key, retval[key]))
+ raise ValueError(
+ "%r.%s conflicts with previous value %r" % (cls, key, retval[key])
+ )
retval[key] = subinst_eater(self, inst, cls)
diff --git a/spyne/protocol/html/__init__.py b/spyne/protocol/html/__init__.py
index 43b6c5caa..532b22e8a 100644
--- a/spyne/protocol/html/__init__.py
+++ b/spyne/protocol/html/__init__.py
@@ -21,14 +21,10 @@
This package contains some basic html output protocols.
"""
-from spyne.protocol.html._base import HtmlBase
-from spyne.protocol.html._base import HtmlCloth
-from spyne.protocol.html._base import parse_html_fragment_file
-from spyne.protocol.html.table import HtmlColumnTable
-from spyne.protocol.html.table import HtmlRowTable
+from spyne.protocol.html._base import HtmlBase, HtmlCloth, parse_html_fragment_file
+from spyne.protocol.html.addtl import BooleanListProtocol, PrettyFormat
from spyne.protocol.html.microformat import HtmlMicroFormat
-from spyne.protocol.html.addtl import PrettyFormat
-from spyne.protocol.html.addtl import BooleanListProtocol
+from spyne.protocol.html.table import HtmlColumnTable, HtmlRowTable
# FIXME: REMOVE ME
diff --git a/spyne/protocol/html/_base.py b/spyne/protocol/html/_base.py
index 142118ea1..bb4eca41c 100644
--- a/spyne/protocol/html/_base.py
+++ b/spyne/protocol/html/_base.py
@@ -18,6 +18,7 @@
#
import logging
+
logger = logging.getLogger(__name__)
from collections import defaultdict
@@ -25,12 +26,10 @@
from lxml import etree, html
from lxml.html.builder import E
-from spyne.util import coroutine, Break, six
-from spyne.util.oset import oset
+from spyne.protocol.cloth._base import XmlCloth, XmlClothProtocolContext
+from spyne.util import Break, coroutine
from spyne.util.etreeconv import dict_to_etree
-
-from spyne.protocol.cloth import XmlCloth
-from spyne.protocol.cloth._base import XmlClothProtocolContext
+from spyne.util.oset import oset
def parse_html_fragment_file(T_FILES):
@@ -57,22 +56,38 @@ def __init__(self, parent, transport, type=None):
class HtmlCloth(XmlCloth):
- mime_type = 'text/html; charset=UTF-8'
-
- def __init__(self, app=None, encoding='utf8',
- mime_type=None, ignore_uncap=False, ignore_wrappers=False,
- cloth=None, cloth_parser=None, polymorphic=True,
- strip_comments=True, hier_delim='.', doctype=None):
-
- super(HtmlCloth, self).__init__(app=app, encoding=encoding,
- mime_type=mime_type, ignore_uncap=ignore_uncap,
- ignore_wrappers=ignore_wrappers, cloth=cloth,
- cloth_parser=cloth_parser, polymorphic=polymorphic,
- strip_comments=strip_comments)
+ mime_type = "text/html; charset=UTF-8"
+
+ def __init__(
+ self,
+ app=None,
+ encoding="utf8",
+ mime_type=None,
+ ignore_uncap=False,
+ ignore_wrappers=False,
+ cloth=None,
+ cloth_parser=None,
+ polymorphic=True,
+ strip_comments=True,
+ hier_delim=".",
+ doctype=None,
+ ):
+
+ super(HtmlCloth, self).__init__(
+ app=app,
+ encoding=encoding,
+ mime_type=mime_type,
+ ignore_uncap=ignore_uncap,
+ ignore_wrappers=ignore_wrappers,
+ cloth=cloth,
+ cloth_parser=cloth_parser,
+ polymorphic=polymorphic,
+ strip_comments=strip_comments,
+ )
self.hier_delim = hier_delim
self.doctype = doctype
- self.default_method = 'html'
+ self.default_method = "html"
def _parse_file(self, file_name, cloth_parser):
if cloth_parser is None:
@@ -102,38 +117,35 @@ def dict_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
@staticmethod
def add_html_attr(attr_name, attr_dict, class_name):
if attr_name in attr_dict:
- attr_dict[attr_name] = ' '.join(
- (attr_dict.get('class', ''), class_name))
+ attr_dict[attr_name] = " ".join((attr_dict.get("class", ""), class_name))
else:
attr_dict[attr_name] = class_name
@staticmethod
def add_style(attr_dict, data):
- style = attr_dict.get('style', None)
+ style = attr_dict.get("style", None)
if style is not None:
- attr_dict['style'] = ';'.join(style, data)
+ attr_dict["style"] = ";".join(style, data)
else:
- attr_dict['style'] = data
+ attr_dict["style"] = data
@staticmethod
def selsafe(s):
- return s.replace('[', '').replace(']', '').replace('.', '__')
+ return s.replace("[", "").replace("]", "").replace(".", "__")
@coroutine
- def complex_to_parent(self, ctx, cls, inst, parent, name, use_ns=False,
- **kwargs):
+ def complex_to_parent(self, ctx, cls, inst, parent, name, use_ns=False, **kwargs):
inst = cls.get_serialization_instance(inst)
# TODO: Put xml attributes as well in the below element() call.
with parent.element(name):
- ret = self._write_members(ctx, cls, inst, parent, use_ns=False,
- **kwargs)
+ ret = self._write_members(ctx, cls, inst, parent, use_ns=False, **kwargs)
if ret is not None:
try:
while True:
- sv2 = (yield) # may throw Break
+ sv2 = yield # may throw Break
ret.send(sv2)
except Break:
@@ -146,16 +158,16 @@ def gen_anchor(self, cls, inst, name, anchor_class=None):
assert name is not None
cls_attrs = self.get_cls_attrs(cls)
- href = getattr(inst, 'href', None)
- if href is None: # this is not a AnyUri.Value instance.
+ href = getattr(inst, "href", None)
+ if href is None: # this is not a AnyUri.Value instance.
href = inst
content = None
text = cls_attrs.text
else:
- content = getattr(inst, 'content', None)
- text = getattr(inst, 'text', None)
+ content = getattr(inst, "content", None)
+ text = getattr(inst, "text", None)
if text is None:
text = cls_attrs.text
@@ -168,10 +180,10 @@ def gen_anchor(self, cls, inst, name, anchor_class=None):
retval = E.a(text)
if href is not None:
- retval.attrib['href'] = href
+ retval.attrib["href"] = href
if anchor_class is not None:
- retval.attrib['class'] = anchor_class
+ retval.attrib["class"] = anchor_class
if content is not None:
retval.append(content)
@@ -184,19 +196,19 @@ def any_uri_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
def imageuri_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
# with ImageUri, content is ignored.
- href = getattr(inst, 'href', None)
- if href is None: # this is not a AnyUri.Value instance.
+ href = getattr(inst, "href", None)
+ if href is None: # this is not a AnyUri.Value instance.
href = inst
- text = getattr(cls.Attributes, 'text', None)
+ text = getattr(cls.Attributes, "text", None)
else:
- text = getattr(inst, 'text', None)
+ text = getattr(inst, "text", None)
if text is None:
- text = getattr(cls.Attributes, 'text', None)
+ text = getattr(cls.Attributes, "text", None)
retval = E.img(src=href)
if text is not None:
- retval.attrib['alt'] = text
+ retval.attrib["alt"] = text
parent.write(retval)
@@ -216,7 +228,7 @@ def null_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
pass
def any_xml_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
- if isinstance(inst, (six.text_type, six.binary_type)):
+ if isinstance(inst, (str, bytes)):
inst = etree.fromstring(inst)
parent.write(inst)
@@ -225,11 +237,11 @@ def any_html_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
cls_attrs = self.get_cls_attrs(cls)
if cls_attrs.as_string:
- if not (isinstance(inst, str) or isinstance(inst, six.text_type)):
+ if not isinstance(inst, str):
inst = html.tostring(inst)
else:
- if isinstance(inst, str) or isinstance(inst, six.text_type):
+ if isinstance(inst, str):
inst = html.fromstring(inst)
parent.write(inst)
@@ -238,7 +250,7 @@ def any_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
parent.write(inst)
def any_dict_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
- elt = E('foo')
+ elt = E("foo")
dict_to_etree(inst, elt)
parent.write(elt[0])
diff --git a/spyne/protocol/html/addtl.py b/spyne/protocol/html/addtl.py
index c89af8aac..1ebf7195e 100644
--- a/spyne/protocol/html/addtl.py
+++ b/spyne/protocol/html/addtl.py
@@ -17,9 +17,10 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
-from lxml.builder import E
from pprint import pformat
+from lxml.builder import E
+
from spyne import Boolean
from spyne.protocol.html import HtmlBase
diff --git a/spyne/protocol/html/microformat.py b/spyne/protocol/html/microformat.py
index b78e1e1c5..74a77c01e 100644
--- a/spyne/protocol/html/microformat.py
+++ b/spyne/protocol/html/microformat.py
@@ -21,22 +21,38 @@
from lxml.html.builder import E
-from spyne.util import six, coroutine, Break
-from spyne.util.cdict import cdict
-
-from spyne.model import Array, AnyHtml, ComplexModelBase, ByteArray, \
- ModelBase, PushBase, ImageUri, AnyUri
-
+from spyne.model import (
+ AnyHtml,
+ AnyUri,
+ Array,
+ ByteArray,
+ ComplexModelBase,
+ ImageUri,
+ ModelBase,
+ PushBase,
+)
from spyne.protocol.html import HtmlBase
+from spyne.util import Break, coroutine
+from spyne.util.cdict import cdict
class HtmlMicroFormat(HtmlBase):
- def __init__(self, app=None, ignore_uncap=False, ignore_wrappers=False,
- cloth=None, cloth_parser=None, polymorphic=True,
- doctype="",
- root_tag='div', child_tag='div', field_name_attr='class',
- field_name_tag=None, field_name_class='field_name',
- before_first_root=None):
+ def __init__(
+ self,
+ app=None,
+ ignore_uncap=False,
+ ignore_wrappers=False,
+ cloth=None,
+ cloth_parser=None,
+ polymorphic=True,
+ doctype="",
+ root_tag="div",
+ child_tag="div",
+ field_name_attr="class",
+ field_name_tag=None,
+ field_name_class="field_name",
+ before_first_root=None,
+ ):
"""Protocol that returns the response object according to the "html
microformat" specification. See
https://en.wikipedia.org/wiki/Microformats for more info.
@@ -53,15 +69,18 @@ def __init__(self, app=None, ignore_uncap=False, ignore_wrappers=False,
field names of the complex object children.
"""
- super(HtmlMicroFormat, self).__init__(app=app,
- ignore_uncap=ignore_uncap, ignore_wrappers=ignore_wrappers,
- cloth=cloth, cloth_parser=cloth_parser, polymorphic=polymorphic,
- hier_delim=None, doctype=doctype)
+ super(HtmlMicroFormat, self).__init__(
+ app=app,
+ ignore_uncap=ignore_uncap,
+ ignore_wrappers=ignore_wrappers,
+ cloth=cloth,
+ cloth_parser=cloth_parser,
+ polymorphic=polymorphic,
+ hier_delim=None,
+ doctype=doctype,
+ )
- if six.PY2:
- text_type = basestring
- else:
- text_type = str
+ text_type = str
assert isinstance(root_tag, text_type)
assert isinstance(child_tag, text_type)
@@ -76,18 +95,19 @@ def __init__(self, app=None, ignore_uncap=False, ignore_wrappers=False,
self.field_name_tag = E(field_name_tag)
self._field_name_class = field_name_class
if before_first_root is not None:
- self.event_manager.add_listener("before_first_root",
- before_first_root)
-
- self.serialization_handlers = cdict({
- Array: self.array_to_parent,
- AnyUri: self.any_uri_to_parent,
- AnyHtml: self.any_html_to_parent,
- ImageUri: self.imageuri_to_parent,
- ByteArray: self.not_supported,
- ModelBase: self.model_base_to_parent,
- ComplexModelBase: self.complex_model_to_parent,
- })
+ self.event_manager.add_listener("before_first_root", before_first_root)
+
+ self.serialization_handlers = cdict(
+ {
+ Array: self.array_to_parent,
+ AnyUri: self.any_uri_to_parent,
+ AnyHtml: self.any_html_to_parent,
+ ImageUri: self.imageuri_to_parent,
+ ByteArray: self.not_supported,
+ ModelBase: self.model_base_to_parent,
+ ComplexModelBase: self.complex_model_to_parent,
+ }
+ )
def anyuri_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
retval = self.gen_anchor(cls, inst, parent)
@@ -99,9 +119,10 @@ def model_base_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
data_str = self.to_unicode(cls, inst)
if self.field_name_tag is not None:
- field_name = cls.Attributes.translations.get( name)
- field_name_tag = self.field_name_tag(field_name,
- **{'class':self._field_name_class})
+ field_name = cls.Attributes.translations.get(name)
+ field_name_tag = self.field_name_tag(
+ field_name, **{"class": self._field_name_class}
+ )
field_name_tag.tail = data_str
retval.append(field_name_tag)
@@ -114,7 +135,7 @@ def start_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
"""This is what subserialize calls"""
# if no doctype was written, write it
- if not getattr(ctx.outprot_ctx, 'doctype_written', False):
+ if not getattr(ctx.outprot_ctx, "doctype_written", False):
if len(ctx.protocol.prot_stack) == 1:
if self.doctype is not None:
parent.write_doctype(self.doctype)
@@ -126,22 +147,23 @@ def start_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
return self.to_parent(ctx, cls, inst, parent, name, **kwargs)
@coroutine
- def complex_model_to_parent(self, ctx, cls, inst, parent, name,
- use_ns=False, **kwargs):
+ def complex_model_to_parent(
+ self, ctx, cls, inst, parent, name, use_ns=False, **kwargs
+ ):
attrs = {self.field_name_attr: name}
- if not getattr(ctx.protocol, 'before_first_root', False):
- self.event_manager.fire_event("before_first_root",
- ctx, cls, inst, parent, name, **kwargs)
+ if not getattr(ctx.protocol, "before_first_root", False):
+ self.event_manager.fire_event(
+ "before_first_root", ctx, cls, inst, parent, name, **kwargs
+ )
ctx.protocol.before_first_root = True
with parent.element(self.root_tag, attrs):
- ret = self._write_members(ctx, cls, inst, parent, use_ns=False,
- **kwargs)
+ ret = self._write_members(ctx, cls, inst, parent, use_ns=False, **kwargs)
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
try:
@@ -154,19 +176,20 @@ def array_to_parent(self, ctx, cls, inst, parent, name, from_arr=False, **kwargs
attrs = {self.field_name_attr: name}
if issubclass(cls, Array):
- cls, = cls._type_info.values()
+ (cls,) = cls._type_info.values()
name = cls.get_type_name()
with parent.element(self.root_tag, attrs):
if isinstance(inst, PushBase):
while True:
- sv = (yield)
- ret = self.to_parent(ctx, cls, sv, parent, name,
- from_arr=True, **kwargs)
+ sv = yield
+ ret = self.to_parent(
+ ctx, cls, sv, parent, name, from_arr=True, **kwargs
+ )
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
try:
@@ -176,12 +199,13 @@ def array_to_parent(self, ctx, cls, inst, parent, name, from_arr=False, **kwargs
else:
for sv in inst:
- ret = self.to_parent(ctx, cls, sv, parent, name,
- from_arr=True, **kwargs)
+ ret = self.to_parent(
+ ctx, cls, sv, parent, name, from_arr=True, **kwargs
+ )
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as e:
try:
@@ -190,8 +214,10 @@ def array_to_parent(self, ctx, cls, inst, parent, name, from_arr=False, **kwargs
pass
def null_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
- return [ E(self.child_tag, **{self.field_name_attr: name}) ]
+ return [E(self.child_tag, **{self.field_name_attr: name})]
+
# FIXME: yuck.
-from spyne.protocol.cloth import XmlCloth
+from spyne.protocol.cloth._base import XmlCloth
+
XmlCloth.HtmlMicroFormat = HtmlMicroFormat
diff --git a/spyne/protocol/html/table/__init__.py b/spyne/protocol/html/table/__init__.py
index 0c52d5792..3b43d9a70 100644
--- a/spyne/protocol/html/table/__init__.py
+++ b/spyne/protocol/html/table/__init__.py
@@ -1,4 +1,3 @@
-
from spyne.protocol.html.table._base import HtmlTableBase
-from spyne.protocol.html.table.row import HtmlRowTable
from spyne.protocol.html.table.column import HtmlColumnTable
+from spyne.protocol.html.table.row import HtmlRowTable
diff --git a/spyne/protocol/html/table/_base.py b/spyne/protocol/html/table/_base.py
index 347141931..87973c7b7 100644
--- a/spyne/protocol/html/table/_base.py
+++ b/spyne/protocol/html/table/_base.py
@@ -22,18 +22,41 @@
class HtmlTableBase(HtmlBase):
- def __init__(self, app=None, ignore_uncap=False, ignore_wrappers=True,
- cloth=None, cloth_parser=None, header=True, table_name_attr='class',
- table_name=None, table_class=None, border=0, row_class=None,
- field_name_attr='class', field_type_name_attr='class',
- cell_class=None, header_cell_class=None, polymorphic=True,
- hier_delim='.', doctype=None, link_gen=None, mrpc_delim_text='|',
- table_width=None):
+ def __init__(
+ self,
+ app=None,
+ ignore_uncap=False,
+ ignore_wrappers=True,
+ cloth=None,
+ cloth_parser=None,
+ header=True,
+ table_name_attr="class",
+ table_name=None,
+ table_class=None,
+ border=0,
+ row_class=None,
+ field_name_attr="class",
+ field_type_name_attr="class",
+ cell_class=None,
+ header_cell_class=None,
+ polymorphic=True,
+ hier_delim=".",
+ doctype=None,
+ link_gen=None,
+ mrpc_delim_text="|",
+ table_width=None,
+ ):
- super(HtmlTableBase, self).__init__(app=app,
- ignore_uncap=ignore_uncap, ignore_wrappers=ignore_wrappers,
- cloth=cloth, cloth_parser=cloth_parser, polymorphic=polymorphic,
- hier_delim=hier_delim, doctype=doctype)
+ super(HtmlTableBase, self).__init__(
+ app=app,
+ ignore_uncap=ignore_uncap,
+ ignore_wrappers=ignore_wrappers,
+ cloth=cloth,
+ cloth_parser=cloth_parser,
+ polymorphic=polymorphic,
+ hier_delim=hier_delim,
+ doctype=doctype,
+ )
self.header = header
self.table_name_attr = table_name_attr
@@ -65,5 +88,4 @@ def add_field_attrs(self, attr_dict, name, cls):
c = c.__extends__
- self.add_html_attr(self.field_type_name_attr, attr_dict,
- ' '.join(types))
+ self.add_html_attr(self.field_type_name_attr, attr_dict, " ".join(types))
diff --git a/spyne/protocol/html/table/column.py b/spyne/protocol/html/table/column.py
index 8ac9abfa8..764612eda 100644
--- a/spyne/protocol/html/table/column.py
+++ b/spyne/protocol/html/table/column.py
@@ -20,16 +20,17 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
from inspect import isgenerator
from lxml.html.builder import E
-from spyne import ModelBase, ComplexModelBase, Array
-from spyne.util import coroutine, Break, urlencode
-from spyne.util.oset import oset
+from spyne import Array, ComplexModelBase, ModelBase
from spyne.protocol.html.table import HtmlTableBase
+from spyne.util import Break, coroutine, urlencode
+from spyne.util.oset import oset
class HtmlColumnTableRowProtocol(object):
@@ -43,7 +44,6 @@ def column_table_after_row(self, ctx, cls, inst, parent, name, **kwargs):
pass
-
class HtmlColumnTable(HtmlTableBase, HtmlColumnTableRowProtocol):
"""Protocol that returns the response object as a html table.
@@ -78,22 +78,25 @@ class HtmlColumnTable(HtmlTableBase, HtmlColumnTableRowProtocol):
"""
def __init__(self, *args, **kwargs):
- before_table = kwargs.pop('before_table', None)
+ before_table = kwargs.pop("before_table", None)
super(HtmlColumnTable, self).__init__(*args, **kwargs)
- self.serialization_handlers.update({
- ModelBase: self.model_base_to_parent,
- ComplexModelBase: self.complex_model_to_parent,
- Array: self.array_to_parent,
- })
+ self.serialization_handlers.update(
+ {
+ ModelBase: self.model_base_to_parent,
+ ComplexModelBase: self.complex_model_to_parent,
+ Array: self.array_to_parent,
+ }
+ )
if before_table is not None:
self.event_manager.add_listener("before_table", before_table)
- def model_base_to_parent(self, ctx, cls, inst, parent, name,
- from_arr=False, **kwargs):
- inst_str = ''
+ def model_base_to_parent(
+ self, ctx, cls, inst, parent, name, from_arr=False, **kwargs
+ ):
+ inst_str = ""
if inst is not None:
inst_str = self.to_unicode(cls, inst)
@@ -108,8 +111,9 @@ def model_base_to_parent(self, ctx, cls, inst, parent, name,
parent.write(inst_str)
@coroutine
- def _gen_row(self, ctx, cls, inst, parent, name, from_arr=False,
- array_index=None, **kwargs):
+ def _gen_row(
+ self, ctx, cls, inst, parent, name, from_arr=False, array_index=None, **kwargs
+ ):
# because HtmlForm* protocols don't use the global null handler, it's
# possible for null values to reach here.
@@ -118,18 +122,16 @@ def _gen_row(self, ctx, cls, inst, parent, name, from_arr=False,
logger.debug("Generate row for %r", cls)
- mrpc_delim_elt = ''
+ mrpc_delim_elt = ""
if self.mrpc_delim_text is not None:
- mrpc_delim_elt = E.span(self.mrpc_delim_text,
- **{'class': 'mrpc-delimiter'})
- mrpc_delim_elt.tail = ' '
+ mrpc_delim_elt = E.span(self.mrpc_delim_text, **{"class": "mrpc-delimiter"})
+ mrpc_delim_elt.tail = " "
- with parent.element('tr'):
+ with parent.element("tr"):
for k, v in self.sort_fields(cls):
cls_attr = self.get_cls_attrs(v)
if cls_attr.exc:
- logger.debug("\tExclude table cell %r type %r for %r",
- k, v, cls)
+ logger.debug("\tExclude table cell %r type %r for %r", k, v, cls)
continue
try:
@@ -145,27 +147,40 @@ def _gen_row(self, ctx, cls, inst, parent, name, from_arr=False,
if array_index is None:
sub_name = "%s%s%s" % (name, self.hier_delim, sub_name)
else:
- sub_name = "%s[%d]%s%s" % (name, array_index,
- self.hier_delim, sub_name)
+ sub_name = "%s[%d]%s%s" % (
+ name,
+ array_index,
+ self.hier_delim,
+ sub_name,
+ )
- logger.debug("\tGenerate table cell %r type %r for %r",
- sub_name, v, cls)
+ logger.debug(
+ "\tGenerate table cell %r type %r for %r", sub_name, v, cls
+ )
td_attrs = {}
self.add_field_attrs(td_attrs, cls_attr.sub_name or k, v)
if cls_attr.hidden:
- self.add_style(td_attrs, 'display:None')
-
- with parent.element('td', td_attrs):
- ret = self.to_parent(ctx, v, sub_value, parent, sub_name,
- from_arr=from_arr, array_index=array_index, **kwargs)
+ self.add_style(td_attrs, "display:None")
+
+ with parent.element("td", td_attrs):
+ ret = self.to_parent(
+ ctx,
+ v,
+ sub_value,
+ parent,
+ sub_name,
+ from_arr=from_arr,
+ array_index=array_index,
+ **kwargs,
+ )
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as b:
@@ -176,9 +191,9 @@ def _gen_row(self, ctx, cls, inst, parent, name, from_arr=False,
m = cls.Attributes.methods
if m is not None and len(m) > 0:
- td_attrs = {'class': 'mrpc-cell'}
+ td_attrs = {"class": "mrpc-cell"}
- with parent.element('td', td_attrs):
+ with parent.element("td", td_attrs):
first = True
for mn, md in self._methods(ctx, cls, inst):
@@ -190,7 +205,7 @@ def _gen_row(self, ctx, cls, inst, parent, name, from_arr=False,
pd = {}
for k, v in self.sort_fields(cls):
- if getattr(v.Attributes, 'primary_key', None):
+ if getattr(v.Attributes, "primary_key", None):
r = self.to_unicode(v, getattr(inst, k, None))
if r is not None:
pd[k] = r
@@ -199,23 +214,25 @@ def _gen_row(self, ctx, cls, inst, parent, name, from_arr=False,
mdid2key = ctx.app.interface.method_descriptor_id_to_key
href = mdid2key[id(md)].rsplit("}", 1)[-1]
- text = md.translate(ctx.locale,
- md.in_message.get_type_name())
- parent.write(E.a(
- text,
- href="%s?%s" % (href, params),
- **{'class': 'mrpc-operation'}
- ))
+ text = md.translate(ctx.locale, md.in_message.get_type_name())
+ parent.write(
+ E.a(
+ text,
+ href="%s?%s" % (href, params),
+ **{"class": "mrpc-operation"},
+ )
+ )
logger.debug("Generate row for %r done.", cls)
- self.extend_data_row(ctx, cls, inst, parent, name,
- array_index=array_index, **kwargs)
+ self.extend_data_row(
+ ctx, cls, inst, parent, name, array_index=array_index, **kwargs
+ )
def _gen_thead(self, ctx, cls, parent, name):
logger.debug("Generate header for %r", cls)
- with parent.element('thead'):
- with parent.element('tr'):
+ with parent.element("thead"):
+ with parent.element("tr"):
if issubclass(cls, ComplexModelBase):
fti = self.sort_fields(cls)
for k, v in fti:
@@ -227,14 +244,14 @@ def _gen_thead(self, ctx, cls, parent, name):
self.add_field_attrs(th_attrs, k, cls)
if cls_attr.hidden:
- self.add_style(th_attrs, 'display:None')
+ self.add_style(th_attrs, "display:None")
header_name = self.trc(v, ctx.locale, k)
parent.write(E.th(header_name, **th_attrs))
m = cls.Attributes.methods
if m is not None and len(m) > 0:
- th_attrs = {'class': 'mrpc-cell'}
+ th_attrs = {"class": "mrpc-cell"}
parent.write(E.th(**th_attrs))
else:
@@ -258,22 +275,22 @@ def _gen_table(self, ctx, cls, inst, parent, name, gen_rows, **kwargs):
table_class.add(self.table_class)
if self.table_name_attr is not None:
- tn = (self.table_name
- if self.table_name is not None else cls.get_type_name())
+ tn = self.table_name if self.table_name is not None else cls.get_type_name()
- if self.table_name_attr == 'class':
+ if self.table_name_attr == "class":
table_class.add(tn)
else:
attrib[self.table_name_attr] = tn
- attrib['class'] = ' '.join(table_class)
+ attrib["class"] = " ".join(table_class)
if self.table_width is not None:
- attrib['width'] = self.table_width
+ attrib["width"] = self.table_width
- self.event_manager.fire_event('before_table', ctx, cls, inst, parent,
- name, prot=self, **kwargs)
+ self.event_manager.fire_event(
+ "before_table", ctx, cls, inst, parent, name, prot=self, **kwargs
+ )
- with parent.element('table', attrib):
+ with parent.element("table", attrib):
write_header = self.header
if cls_attrs.header is False:
write_header = cls_attrs.header
@@ -283,17 +300,16 @@ def _gen_table(self, ctx, cls, inst, parent, name, gen_rows, **kwargs):
subprot = self.get_subprot(ctx, cls_attrs)
if subprot is not None:
- ret = subprot.column_table_gen_header(ctx, cls, parent,
- name)
+ ret = subprot.column_table_gen_header(ctx, cls, parent, name)
if not ret:
self._gen_thead(ctx, cls, parent, name)
- with parent.element('tbody'):
+ with parent.element("tbody"):
ret = gen_rows(ctx, cls, inst, parent, name, **kwargs)
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as b:
try:
@@ -303,19 +319,28 @@ def _gen_table(self, ctx, cls, inst, parent, name, gen_rows, **kwargs):
self.extend_table(ctx, cls, parent, name, **kwargs)
- def complex_model_to_parent(self, ctx, cls, inst, parent, name,
- from_arr=False, **kwargs):
+ def complex_model_to_parent(
+ self, ctx, cls, inst, parent, name, from_arr=False, **kwargs
+ ):
# If this is direct child of an array, table is already set up in
# array_to_parent.
if from_arr:
return self._gen_row(ctx, cls, inst, parent, name, **kwargs)
else:
- return self.wrap_table(ctx, cls, inst, parent, name, self._gen_row,
- **kwargs)
+ return self.wrap_table(
+ ctx, cls, inst, parent, name, self._gen_row, **kwargs
+ )
def array_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
- return self.wrap_table(ctx, cls, inst, parent, name,
- super(HtmlColumnTable, self).array_to_parent, **kwargs)
+ return self.wrap_table(
+ ctx,
+ cls,
+ inst,
+ parent,
+ name,
+ super(HtmlColumnTable, self).array_to_parent,
+ **kwargs,
+ )
def wrap_table(self, ctx, cls, inst, parent, name, gen_rows, **kwargs):
return self._gen_table(ctx, cls, inst, parent, name, gen_rows, **kwargs)
diff --git a/spyne/protocol/html/table/row.py b/spyne/protocol/html/table/row.py
index 5a33e1a0a..e00c07203 100644
--- a/spyne/protocol/html/table/row.py
+++ b/spyne/protocol/html/table/row.py
@@ -20,17 +20,17 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
from inspect import isgenerator
from lxml.html.builder import E
-from spyne import ModelBase, ByteArray, ComplexModelBase, Array, AnyUri, \
- ImageUri
-from spyne.util import coroutine, Break
-from spyne.util.cdict import cdict
+from spyne import AnyUri, Array, ByteArray, ComplexModelBase, ImageUri, ModelBase
from spyne.protocol.html.table import HtmlTableBase
+from spyne.util import Break, coroutine
+from spyne.util.cdict import cdict
class HtmlRowTable(HtmlTableBase):
@@ -63,17 +63,20 @@ class HtmlRowTable(HtmlTableBase):
def __init__(self, *args, **kwargs):
super(HtmlRowTable, self).__init__(*args, **kwargs)
- self.serialization_handlers = cdict({
- ModelBase: self.model_base_to_parent,
- AnyUri: self.any_uri_to_parent,
- ImageUri: self.imageuri_to_parent,
- ByteArray: self.not_supported,
- ComplexModelBase: self.complex_model_to_parent,
- Array: self.array_to_parent,
- })
-
- def model_base_to_parent(self, ctx, cls, inst, parent, name, from_arr=False,
- **kwargs):
+ self.serialization_handlers = cdict(
+ {
+ ModelBase: self.model_base_to_parent,
+ AnyUri: self.any_uri_to_parent,
+ ImageUri: self.imageuri_to_parent,
+ ByteArray: self.not_supported,
+ ComplexModelBase: self.complex_model_to_parent,
+ Array: self.array_to_parent,
+ }
+ )
+
+ def model_base_to_parent(
+ self, ctx, cls, inst, parent, name, from_arr=False, **kwargs
+ ):
if from_arr:
td_attrib = {}
if False and self.field_name_attr:
@@ -84,21 +87,23 @@ def model_base_to_parent(self, ctx, cls, inst, parent, name, from_arr=False,
parent.write(self.to_unicode(cls, inst))
@coroutine
- def complex_model_to_parent(self, ctx, cls, inst, parent, name,
- from_arr=False, **kwargs):
+ def complex_model_to_parent(
+ self, ctx, cls, inst, parent, name, from_arr=False, **kwargs
+ ):
attrib = {}
if self.table_name_attr is not None:
attrib[self.table_name_attr] = cls.get_type_name()
if self.table_width is not None:
- attrib['width'] = self.table_width
+ attrib["width"] = self.table_width
- with parent.element('table', attrib):
- with parent.element('tbody'):
+ with parent.element("table", attrib):
+ with parent.element("tbody"):
for k, v in self.sort_fields(cls):
sub_attrs = self.get_cls_attrs(v)
if sub_attrs.exc:
- logger.debug("\tExclude table cell %r type %r for %r",
- k, v, cls)
+ logger.debug(
+ "\tExclude table cell %r type %r for %r", k, v, cls
+ )
continue
try:
sub_value = getattr(inst, k, None)
@@ -111,43 +116,43 @@ def complex_model_to_parent(self, ctx, cls, inst, parent, name,
tr_attrs = {}
if self.row_class is not None:
- self.add_html_attr('class', tr_attrs, self.row_class)
+ self.add_html_attr("class", tr_attrs, self.row_class)
- with parent.element('tr', tr_attrs):
+ with parent.element("tr", tr_attrs):
th_attrs = {}
if self.header_cell_class is not None:
- self.add_html_attr('class', th_attrs,
- self.header_cell_class)
+ self.add_html_attr(
+ "class", th_attrs, self.header_cell_class
+ )
self.add_field_attrs(th_attrs, sub_name, v)
if sub_attrs.hidden:
- self.add_style(th_attrs, 'display:None')
+ self.add_style(th_attrs, "display:None")
if self.header:
- parent.write(E.th(
- self.trc(v, ctx.locale, sub_name),
- **th_attrs
- ))
+ parent.write(
+ E.th(self.trc(v, ctx.locale, sub_name), **th_attrs)
+ )
td_attrs = {}
if self.cell_class is not None:
- self.add_html_attr('class', td_attrs,
- self.cell_class)
+ self.add_html_attr("class", td_attrs, self.cell_class)
self.add_field_attrs(td_attrs, sub_name, v)
if sub_attrs.hidden:
- self.add_style(td_attrs, 'display:None')
+ self.add_style(td_attrs, "display:None")
- with parent.element('td', td_attrs):
- ret = self.to_parent(ctx, v, sub_value, parent,
- sub_name, **kwargs)
+ with parent.element("td", td_attrs):
+ ret = self.to_parent(
+ ctx, v, sub_value, parent, sub_name, **kwargs
+ )
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as b:
try:
@@ -157,14 +162,15 @@ def complex_model_to_parent(self, ctx, cls, inst, parent, name,
@coroutine
def array_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
- with parent.element('div'):
+ with parent.element("div"):
if issubclass(cls, ComplexModelBase):
ret = super(HtmlRowTable, self).array_to_parent(
- ctx, cls, inst, parent, name, **kwargs)
+ ctx, cls, inst, parent, name, **kwargs
+ )
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as b:
try:
@@ -176,38 +182,38 @@ def array_to_parent(self, ctx, cls, inst, parent, name, **kwargs):
if self.table_name_attr:
table_attrib = {self.table_name_attr: name}
if self.table_width is not None:
- table_attrib['width'] = self.table_width
+ table_attrib["width"] = self.table_width
- with parent.element('table', table_attrib):
+ with parent.element("table", table_attrib):
tr_attrib = {}
if self.row_class is not None:
- tr_attrib['class'] = self.row_class
- with parent.element('tr', tr_attrib):
+ tr_attrib["class"] = self.row_class
+ with parent.element("tr", tr_attrib):
if self.header:
- parent.write(E.th(self.trc(cls, ctx.locale,
- cls.get_type_name())))
+ parent.write(
+ E.th(self.trc(cls, ctx.locale, cls.get_type_name()))
+ )
td_attrs = {}
if self.cell_class is not None:
- self.add_html_attr('class', td_attrs,
- self.cell_class)
+ self.add_html_attr("class", td_attrs, self.cell_class)
self.add_field_attrs(td_attrs, name, cls)
cls_attrs = self.get_cls_attrs(cls)
if cls_attrs.hidden:
- self.add_style(td_attrs, 'display:None')
+ self.add_style(td_attrs, "display:None")
- with parent.element('td', td_attrs):
- with parent.element('table'):
- ret = super(HtmlRowTable, self) \
- .array_to_parent(ctx, cls, inst, parent,
- name, **kwargs)
+ with parent.element("td", td_attrs):
+ with parent.element("table"):
+ ret = super(HtmlRowTable, self).array_to_parent(
+ ctx, cls, inst, parent, name, **kwargs
+ )
if isgenerator(ret):
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as b:
try:
diff --git a/spyne/protocol/http.py b/spyne/protocol/http.py
index b351d8169..b05b79082 100644
--- a/spyne/protocol/http.py
+++ b/spyne/protocol/http.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -27,20 +26,22 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
import re
-import pytz
import tempfile
+from io import BytesIO
+
+import pytz
-from spyne import BODY_STYLE_WRAPPED, MethodDescriptor, PushBase
-from spyne.util import six, coroutine, Break
-from spyne.util.six import string_types, BytesIO
+from spyne.descriptor import BODY_STYLE_WRAPPED, MethodDescriptor
from spyne.error import ResourceNotFoundError
+from spyne.model._base import PushBase
from spyne.model.binary import BINARY_ENCODING_URLSAFE_BASE64, File
from spyne.model.primitive import DateTime
from spyne.protocol.dictdoc import SimpleDictDocument
-
+from spyne.util import Break, coroutine
TEMPORARY_DIR = None
STREAM_READ_BLOCK_SIZE = 0x4000
@@ -49,7 +50,7 @@
_OctalPatt = re.compile(r"\\[0-3][0-7][0-7]")
_QuotePatt = re.compile(r"[\\].")
-_nulljoin = ''.join
+_nulljoin = "".join
# this is twisted's _idnaBytes. it's not possible to import twisted at this
@@ -92,7 +93,7 @@ def _unquote_cookie(str):
while 0 <= i < n:
o_match = _OctalPatt.search(str, i)
q_match = _QuotePatt.search(str, i)
- if not o_match and not q_match: # Neither matched
+ if not o_match and not q_match: # Neither matched
res.append(str[i:])
break
# else:
@@ -101,13 +102,13 @@ def _unquote_cookie(str):
j = o_match.start(0)
if q_match:
k = q_match.start(0)
- if q_match and (not o_match or k < j): # QuotePatt matched
+ if q_match and (not o_match or k < j): # QuotePatt matched
res.append(str[i:k])
- res.append(str[k+1])
+ res.append(str[k + 1])
i = k + 2
- else: # OctalPatt matched
+ else: # OctalPatt matched
res.append(str[i:j])
- res.append(chr(int(str[j+1:j+4], 8)))
+ res.append(chr(int(str[j + 1 : j + 4], 8)))
i = j + 4
return _nulljoin(res)
@@ -122,13 +123,13 @@ def _parse_cookie(cookie):
retval = {}
- for chunk in cookie.split(';'):
- if '=' in chunk:
- key, val = chunk.split('=', 1)
+ for chunk in cookie.split(";"):
+ if "=" in chunk:
+ key, val = chunk.split("=", 1)
else:
# Assume an empty name per
# https://bugzilla.mozilla.org/show_bug.cgi?id=169091
- key, val = '', chunk
+ key, val = "", chunk
key, val = key.strip(), val.strip()
if key or val:
@@ -139,16 +140,15 @@ def _parse_cookie(cookie):
def get_stream_factory(dir=None, delete=True):
- def stream_factory(total_content_length, filename, content_type,
- content_length=None):
- if total_content_length >= SWAP_DATA_TO_FILE_THRESHOLD or \
- delete == False:
+ def stream_factory(
+ total_content_length, filename, content_type, content_length=None
+ ):
+ if total_content_length >= SWAP_DATA_TO_FILE_THRESHOLD or delete == False:
if delete == False:
# You need python >= 2.6 for this.
- retval = tempfile.NamedTemporaryFile('wb+', dir=dir,
- delete=delete)
+ retval = tempfile.NamedTemporaryFile("wb+", dir=dir, delete=delete)
else:
- retval = tempfile.NamedTemporaryFile('wb+', dir=dir)
+ retval = tempfile.NamedTemporaryFile("wb+", dir=dir)
else:
retval = BytesIO()
@@ -156,9 +156,24 @@ def stream_factory(total_content_length, filename, content_type,
return stream_factory
+
_weekday = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
-_month = ['w00t', "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
- "Oct", "Nov", "Dec"]
+_month = [
+ "w00t",
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+]
+
def _header_to_bytes(prot, val, cls):
if issubclass(cls, DateTime):
@@ -168,8 +183,14 @@ def _header_to_bytes(prot, val, cls):
val = val.replace(tzinfo=pytz.utc)
return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (
- _weekday[val.weekday()], val.day, _month[val.month],
- val.year, val.hour, val.minute, val.second)
+ _weekday[val.weekday()],
+ val.day,
+ _month[val.month],
+ val.year,
+ val.hour,
+ val.minute,
+ val.second,
+ )
else:
# because wsgi_ref wants header values in unicode.
return prot.to_unicode(cls, val)
@@ -194,19 +215,33 @@ class HttpRpc(SimpleDictDocument):
value.
"""
- mime_type = 'text/plain'
+ mime_type = "text/plain"
default_binary_encoding = BINARY_ENCODING_URLSAFE_BASE64
- default_string_encoding = 'UTF-8'
+ default_string_encoding = "UTF-8"
type = set(SimpleDictDocument.type)
- type.add('http')
-
- def __init__(self, app=None, validator=None, mime_type=None,
- tmp_dir=None, tmp_delete_on_close=True, ignore_uncap=False,
- parse_cookie=True, hier_delim=".", strict_arrays=False):
- super(HttpRpc, self).__init__(app, validator, mime_type,
- ignore_uncap=ignore_uncap, hier_delim=hier_delim,
- strict_arrays=strict_arrays)
+ type.add("http")
+
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ mime_type=None,
+ tmp_dir=None,
+ tmp_delete_on_close=True,
+ ignore_uncap=False,
+ parse_cookie=True,
+ hier_delim=".",
+ strict_arrays=False,
+ ):
+ super(HttpRpc, self).__init__(
+ app,
+ validator,
+ mime_type,
+ ignore_uncap=ignore_uncap,
+ hier_delim=hier_delim,
+ strict_arrays=strict_arrays,
+ )
self.tmp_dir = tmp_dir
self.tmp_delete_on_close = tmp_delete_on_close
@@ -217,14 +252,14 @@ def get_tmp_delete_on_close(self):
def set_tmp_delete_on_close(self, val):
self.__tmp_delete_on_close = val
- self.stream_factory = get_stream_factory(self.tmp_dir,
- self.__tmp_delete_on_close)
+ self.stream_factory = get_stream_factory(
+ self.tmp_dir, self.__tmp_delete_on_close
+ )
- tmp_delete_on_close = property(get_tmp_delete_on_close,
- set_tmp_delete_on_close)
+ tmp_delete_on_close = property(get_tmp_delete_on_close, set_tmp_delete_on_close)
def set_validator(self, validator):
- if validator == 'soft' or validator is self.SOFT_VALIDATION:
+ if validator == "soft" or validator is self.SOFT_VALIDATION:
self.validator = self.SOFT_VALIDATION
elif validator is None:
self.validator = None
@@ -232,9 +267,12 @@ def set_validator(self, validator):
raise ValueError(validator)
def create_in_document(self, ctx, in_string_encoding=None):
- assert ctx.transport.type.endswith('http'), \
- ("This protocol only works with an http transport, not %r, (in %r)"
- % (ctx.transport.type, ctx.transport))
+ assert ctx.transport.type.endswith(
+ "http"
+ ), "This protocol only works with an http transport, not %r, (in %r)" % (
+ ctx.transport.type,
+ ctx.transport,
+ )
ctx.in_document = ctx.transport.req
ctx.transport.request_encoding = in_string_encoding
@@ -242,13 +280,12 @@ def create_in_document(self, ctx, in_string_encoding=None):
def decompose_incoming_envelope(self, ctx, message_type):
assert message_type == SimpleDictDocument.REQUEST
- ctx.transport.itself.decompose_incoming_envelope(
- self, ctx, message_type)
+ ctx.transport.itself.decompose_incoming_envelope(self, ctx, message_type)
if self.parse_cookie:
- cookies = ctx.in_header_doc.get('cookie', None)
+ cookies = ctx.in_header_doc.get("cookie", None)
if cookies is None:
- cookies = ctx.in_header_doc.get('Cookie', None)
+ cookies = ctx.in_header_doc.get("Cookie", None)
if cookies is not None:
for cookie_string in cookies:
@@ -259,32 +296,38 @@ def decompose_incoming_envelope(self, ctx, message_type):
l.append(v)
ctx.in_header_doc[k] = l
- logger.debug('\theader : %r' % (ctx.in_header_doc))
- logger.debug('\tbody : %r' % (ctx.in_body_doc))
+ logger.debug("\theader : %r" % (ctx.in_header_doc))
+ logger.debug("\tbody : %r" % (ctx.in_body_doc))
def deserialize(self, ctx, message):
assert message in (self.REQUEST,)
- self.event_manager.fire_event('before_deserialize', ctx)
+ self.event_manager.fire_event("before_deserialize", ctx)
if ctx.descriptor is None:
raise ResourceNotFoundError(ctx.method_request_string)
- req_enc = getattr(ctx.transport, 'request_encoding', None)
+ req_enc = getattr(ctx.transport, "request_encoding", None)
if req_enc is None:
req_enc = ctx.in_protocol.default_string_encoding
if ctx.descriptor.in_header is not None:
# HttpRpc supports only one header class
in_header_class = ctx.descriptor.in_header[0]
- ctx.in_header = self.simple_dict_to_object(ctx, ctx.in_header_doc,
- in_header_class, self.validator, req_enc=req_enc)
+ ctx.in_header = self.simple_dict_to_object(
+ ctx, ctx.in_header_doc, in_header_class, self.validator, req_enc=req_enc
+ )
if ctx.descriptor.in_message is not None:
- ctx.in_object = self.simple_dict_to_object(ctx, ctx.in_body_doc,
- ctx.descriptor.in_message, self.validator, req_enc=req_enc)
+ ctx.in_object = self.simple_dict_to_object(
+ ctx,
+ ctx.in_body_doc,
+ ctx.descriptor.in_message,
+ self.validator,
+ req_enc=req_enc,
+ )
- self.event_manager.fire_event('after_deserialize', ctx)
+ self.event_manager.fire_event("after_deserialize", ctx)
def serialize(self, ctx, message):
retval = None
@@ -295,13 +338,13 @@ def serialize(self, ctx, message):
return
if ctx.out_error is not None:
- ctx.transport.mime_type = 'text/plain'
+ ctx.transport.mime_type = "text/plain"
ctx.out_document = ctx.out_error.to_bytes_iterable(ctx.out_error)
else:
retval = self._handle_rpc(ctx)
- self.event_manager.fire_event('serialize', ctx)
+ self.event_manager.fire_event("serialize", ctx)
return retval
@@ -316,21 +359,25 @@ def _handle_rpc_nonempty(self, ctx):
fti = result_class.get_flat_type_info(result_class)
if len(fti) > 1 and not self.ignore_uncap:
- raise TypeError("HttpRpc protocol can only serialize "
- "functions with a single return type.")
+ raise TypeError(
+ "HttpRpc protocol can only serialize "
+ "functions with a single return type."
+ )
if len(fti) == 1:
- out_class, = fti.values()
- out_object, = ctx.out_object
+ (out_class,) = fti.values()
+ (out_object,) = ctx.out_object
else:
out_class = result_class
- out_object, = ctx.out_object
+ (out_object,) = ctx.out_object
if out_class is not None:
- if issubclass(out_class, File) and not \
- isinstance(out_object, (list, tuple, string_types)) \
- and out_object.type is not None:
+ if (
+ issubclass(out_class, File)
+ and not isinstance(out_object, (list, tuple, str))
+ and out_object.type is not None
+ ):
ctx.transport.set_mime_type(str(out_object.type))
ret = self.to_bytes_iterable(out_class, out_object)
@@ -349,7 +396,7 @@ def _handle_rpc(self, ctx):
# assign raw result to its wrapper, result_message
if ctx.out_object is None or len(ctx.out_object) < 1:
- ctx.out_document = ['']
+ ctx.out_document = [""]
else:
retval = self._handle_rpc_nonempty(ctx)
@@ -365,33 +412,34 @@ def _handle_rpc(self, ctx):
if isinstance(ctx.out_header, (list, tuple)):
out_header = ctx.out_header[0]
- ctx.out_header_doc = self.object_to_simple_dict(header_class,
- out_header, subinst_eater=_header_to_bytes)
+ ctx.out_header_doc = self.object_to_simple_dict(
+ header_class, out_header, subinst_eater=_header_to_bytes
+ )
return retval
- def create_out_string(self, ctx, out_string_encoding='utf8'):
+ def create_out_string(self, ctx, out_string_encoding="utf8"):
if ctx.out_string is not None:
return
ctx.out_string = ctx.out_document
def boolean_from_bytes(self, cls, string):
- return string.lower() in ('true', '1', 'checked', 'on')
+ return string.lower() in ("true", "1", "checked", "on")
def integer_from_bytes(self, cls, string):
- if string == '':
+ if string == "":
return None
return super(HttpRpc, self).integer_from_bytes(cls, string)
-_fragment_pattern_re = re.compile('<([A-Za-z0-9_]+)>')
-_full_pattern_re = re.compile('{([A-Za-z0-9_]+)}')
+_fragment_pattern_re = re.compile("<([A-Za-z0-9_]+)>")
+_full_pattern_re = re.compile("{([A-Za-z0-9_]+)}")
-_fragment_pattern_b_re = re.compile(b'<([A-Za-z0-9_]+)>')
-_full_pattern_b_re = re.compile(b'{([A-Za-z0-9_]+)}')
+_fragment_pattern_b_re = re.compile(b"<([A-Za-z0-9_]+)>")
+_full_pattern_b_re = re.compile(b"{([A-Za-z0-9_]+)}")
class HttpPattern(object):
@@ -402,9 +450,9 @@ class HttpPattern(object):
:param host: HTTP "Host:" header pattern
"""
- URL_ENCODING = 'utf8'
- HOST_ENCODING = 'idna'
- VERB_ENCODING = 'latin1' # actually ascii but latin1 is what pep 333 needs
+ URL_ENCODING = "utf8"
+ HOST_ENCODING = "idna"
+ VERB_ENCODING = "latin1" # actually ascii but latin1 is what pep 333 needs
@classmethod
def _compile_url_pattern(cls, pattern_s):
@@ -413,14 +461,13 @@ def _compile_url_pattern(cls, pattern_s):
if pattern_s is None:
return None, None
- if not six.PY2:
- assert isinstance(pattern_s, six.text_type)
- pattern = _fragment_pattern_re.sub(r'(?P<\1>[^/]*)', pattern_s)
- pattern = _full_pattern_re.sub(r'(?P<\1>[^/]*)', pattern)
+ assert isinstance(pattern_s, str)
+ pattern = _fragment_pattern_re.sub(r"(?P<\1>[^/]*)", pattern_s)
+ pattern = _full_pattern_re.sub(r"(?P<\1>[^/]*)", pattern)
pattern_b = pattern_s.encode(cls.URL_ENCODING)
- pattern_b = _fragment_pattern_b_re.sub(b'(?P<\\1>[^/]*)', pattern_b)
- pattern_b = _full_pattern_b_re.sub(b'(?P<\\1>[^/]*)', pattern_b)
+ pattern_b = _fragment_pattern_b_re.sub(b"(?P<\\1>[^/]*)", pattern_b)
+ pattern_b = _full_pattern_b_re.sub(b"(?P<\\1>[^/]*)", pattern_b)
return re.compile(pattern), re.compile(pattern_b)
@@ -431,12 +478,12 @@ def _compile_host_pattern(cls, pattern):
if pattern is None:
return None, None
- pattern = _fragment_pattern_re.sub(r'(?P<\1>[^\.]*)', pattern)
- pattern = _full_pattern_re.sub(r'(?P<\1>.*)', pattern)
+ pattern = _fragment_pattern_re.sub(r"(?P<\1>[^\.]*)", pattern)
+ pattern = _full_pattern_re.sub(r"(?P<\1>.*)", pattern)
pattern_b = pattern.encode(cls.HOST_ENCODING)
- pattern_b = _fragment_pattern_b_re.sub(b'(?P<\\1>[^\.]*)', pattern_b)
- pattern_b = _full_pattern_b_re.sub(b'(?P<\\1>.*)', pattern_b)
+ pattern_b = _fragment_pattern_b_re.sub(rb"(?P<\1>[^.]*)", pattern_b)
+ pattern_b = _full_pattern_b_re.sub(b"(?P<\\1>.*)", pattern_b)
return re.compile(pattern), re.compile(pattern_b)
@@ -447,12 +494,12 @@ def _compile_verb_pattern(cls, pattern):
if pattern is None:
return None, None
- pattern = _fragment_pattern_re.sub(r'(?P<\1>.*)', pattern)
- pattern = _full_pattern_re.sub(r'(?P<\1>.*)', pattern)
+ pattern = _fragment_pattern_re.sub(r"(?P<\1>.*)", pattern)
+ pattern = _full_pattern_re.sub(r"(?P<\1>.*)", pattern)
pattern_b = pattern.encode(cls.VERB_ENCODING)
- pattern_b = _fragment_pattern_b_re.sub(b'(?P<\\1>.*)', pattern_b)
- pattern_b = _full_pattern_b_re.sub(b'(?P<\\1>.*)', pattern_b)
+ pattern_b = _fragment_pattern_b_re.sub(b"(?P<\\1>.*)", pattern_b)
+ pattern_b = _full_pattern_b_re.sub(b"(?P<\\1>.*)", pattern_b)
return re.compile(pattern), re.compile(pattern_b)
@@ -477,8 +524,8 @@ def address(self):
@address.setter
def address(self, what):
- if what is not None and not what.startswith('/'):
- what = '/{}'.format(what)
+ if what is not None and not what.startswith("/"):
+ what = "/{}".format(what)
self.__address = what
self.address_re, self.address_b_re = self._compile_url_pattern(what)
@@ -503,6 +550,7 @@ def verb(self, what):
def as_werkzeug_rule(self):
from werkzeug.routing import Rule
+
from spyne.util.invregexp import invregexp
methods = None
@@ -511,13 +559,17 @@ def as_werkzeug_rule(self):
host = self.host
if host is None:
- host = '<__ignored>' # for some reason, this is necessary when
- # host_matching is enabled.
+ host = "<__ignored>" # for some reason, this is necessary when
+ # host_matching is enabled.
- return Rule(self.address, host=host, endpoint=self.endpoint.name,
- methods=methods)
+ return Rule(
+ self.address, host=host, endpoint=self.endpoint.name, methods=methods
+ )
def __repr__(self):
return "HttpPattern(address=%r, host=%r, verb=%r, endpoint=%r)" % (
- self.address, self.host, self.verb,
- None if self.endpoint is None else self.endpoint.name)
+ self.address,
+ self.host,
+ self.verb,
+ None if self.endpoint is None else self.endpoint.name,
+ )
diff --git a/spyne/protocol/json.py b/spyne/protocol/json.py
index 16acb11f3..28d08cc94 100644
--- a/spyne/protocol/json.py
+++ b/spyne/protocol/json.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -27,17 +26,17 @@
The JSON standard does not define every type that Spyne supports. These include
Date/Time types as well as arbitrary-length integers and arbitrary-precision
-decimals. Integers are parsed to ``int``\s or ``long``\s seamlessly but
-``Decimal``\s are only parsed correctly when they come off as strings.
+decimals. Integers are parsed to ``int``\\s or ``long``\\s seamlessly but
+``Decimal``\\s are only parsed correctly when they come off as strings.
-While it's possible to e.g. (de)serialize floats to ``Decimal``\s by adding
+While it's possible to e.g. (de)serialize floats to ``Decimal``\\s by adding
hooks to ``parse_float`` [#]_ (and convert later as necessary), such
customizations apply to the whole incoming document which pretty much messes up
``AnyDict`` serialization and deserialization.
It also wasn't possible to work with ``object_pairs_hook`` as Spyne's parsing
is always "from outside to inside" whereas ``object_pairs_hook`` is passed
-``dict``\s basically in any order "from inside to outside".
+``dict``\\s basically in any order "from inside to outside".
.. [#] http://docs.python.org/2/library/json.html#json.loads
"""
@@ -45,30 +44,23 @@
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
from itertools import chain
-from spyne.util import six
-
try:
import simplejson as json
from simplejson.decoder import JSONDecodeError
except ImportError:
import json
- JSONDecodeError = ValueError
-from spyne.error import ValidationError
-from spyne.error import ResourceNotFoundError
+ JSONDecodeError = ValueError
+from spyne.error import ResourceNotFoundError, ValidationError
from spyne.model.binary import BINARY_ENCODING_BASE64
-from spyne.model.primitive import Date
-from spyne.model.primitive import Time
-from spyne.model.primitive import DateTime
-from spyne.model.primitive import Double
-from spyne.model.primitive import Integer
-from spyne.model.primitive import Boolean
from spyne.model.fault import Fault
+from spyne.model.primitive import Boolean, Date, DateTime, Double, Integer, Time
from spyne.protocol.dictdoc import HierDictDocument
@@ -86,7 +78,7 @@ def default(self, o):
return list(o)
-NON_NUMBER_TYPES = tuple({list, dict, six.text_type, six.binary_type})
+NON_NUMBER_TYPES = tuple({list, dict, str, bytes})
class JsonDocument(HierDictDocument):
@@ -98,30 +90,46 @@ class JsonDocument(HierDictDocument):
serialized to a list of values instead of a dict of key/value pairs.
"""
- mime_type = 'application/json'
+ mime_type = "application/json"
text_based = True
type = set(HierDictDocument.type)
- type.add('json')
+ type.add("json")
default_binary_encoding = BINARY_ENCODING_BASE64
# flags used just for tests
_decimal_as_string = True
- def __init__(self, app=None, validator=None, mime_type=None,
- ignore_uncap=False,
- # DictDocument specific
- ignore_wrappers=True, complex_as=dict, ordered=False,
- default_string_encoding=None, polymorphic=False,
- **kwargs):
-
- super(JsonDocument, self).__init__(app, validator, mime_type, ignore_uncap,
- ignore_wrappers, complex_as, ordered, polymorphic)
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ mime_type=None,
+ ignore_uncap=False,
+ # DictDocument specific
+ ignore_wrappers=True,
+ complex_as=dict,
+ ordered=False,
+ default_string_encoding=None,
+ polymorphic=False,
+ **kwargs,
+ ):
+
+ super(JsonDocument, self).__init__(
+ app,
+ validator,
+ mime_type,
+ ignore_uncap,
+ ignore_wrappers,
+ complex_as,
+ ordered,
+ polymorphic,
+ )
# this is needed when we're overriding a regular instance attribute
# with a property.
- self.__message = HierDictDocument.__getattribute__(self, 'message')
+ self.__message = HierDictDocument.__getattribute__(self, "message")
self._from_unicode_handlers[Double] = self._ret_number
self._from_unicode_handlers[Boolean] = self._ret_bool
@@ -153,8 +161,8 @@ def validate(self, key, cls, val):
super(JsonDocument, self).validate(key, cls, val)
if issubclass(cls, (DateTime, Date, Time)) and not (
- isinstance(val, six.string_types) and
- cls.validate_string(cls, val)):
+ isinstance(val, str) and cls.validate_string(cls, val)
+ ):
raise ValidationError(key, val)
@property
@@ -163,16 +171,16 @@ def message(self):
@message.setter
def message(self, val):
- if val is self.RESPONSE and not ('cls' in self.kwargs):
- self.kwargs['cls'] = JsonEncoder
+ if val is self.RESPONSE and not ("cls" in self.kwargs):
+ self.kwargs["cls"] = JsonEncoder
self.__message = val
def create_in_document(self, ctx, in_string_encoding=None):
"""Sets ``ctx.in_document`` using ``ctx.in_string``."""
try:
- in_string = b''.join(ctx.in_string)
- if not isinstance(in_string, six.text_type):
+ in_string = b"".join(ctx.in_string)
+ if not isinstance(in_string, str):
if in_string_encoding is None:
in_string_encoding = self.default_string_encoding
if in_string_encoding is not None:
@@ -180,17 +188,17 @@ def create_in_document(self, ctx, in_string_encoding=None):
ctx.in_document = json.loads(in_string, **self.kwargs)
except JSONDecodeError as e:
- raise Fault('Client.JsonDecodeError', repr(e))
+ raise Fault("Client.JsonDecodeError", repr(e))
- def create_out_string(self, ctx, out_string_encoding='utf8'):
+ def create_out_string(self, ctx, out_string_encoding="utf8"):
"""Sets ``ctx.out_string`` using ``ctx.out_document``."""
if out_string_encoding is None:
- ctx.out_string = (json.dumps(o, **self.kwargs)
- for o in ctx.out_document)
+ ctx.out_string = (json.dumps(o, **self.kwargs) for o in ctx.out_document)
else:
ctx.out_string = (
json.dumps(o, **self.kwargs).encode(out_string_encoding)
- for o in ctx.out_document)
+ for o in ctx.out_document
+ )
# Continuation of http://stackoverflow.com/a/24184379/1520211
@@ -227,12 +235,11 @@ class HybridHttpJsonDocument(JsonDocument):
def create_in_document(self, ctx, in_string_encoding=None):
super(HybridHttpJsonDocument, self).create_in_document(ctx)
- url_fragment = ctx.transport.get_path().split('/')[-1]
+ url_fragment = ctx.transport.get_path().split("/")[-1]
ctx.in_document = {url_fragment: ctx.in_document}
-
class JsonP(JsonDocument):
"""The JsonP protocol puts the reponse document inside a designated
javascript function call. The input protocol is identical to the
@@ -245,36 +252,37 @@ class JsonP(JsonDocument):
"""
type = set(HierDictDocument.type)
- type.add('jsonp')
+ type.add("jsonp")
def __init__(self, callback_name, *args, **kwargs):
super(JsonP, self).__init__(*args, **kwargs)
self.callback_name = callback_name
- def create_out_string(self, ctx, out_string_encoding='utf8'):
- super(JsonP, self).create_out_string(ctx,
- out_string_encoding=out_string_encoding)
+ def create_out_string(self, ctx, out_string_encoding="utf8"):
+ super(JsonP, self).create_out_string(
+ ctx, out_string_encoding=out_string_encoding
+ )
if out_string_encoding is None:
ctx.out_string = chain(
- (self.callback_name, '('),
- ctx.out_string,
- (');',),
- )
+ (self.callback_name, "("),
+ ctx.out_string,
+ (");",),
+ )
else:
ctx.out_string = chain(
- [self.callback_name.encode(out_string_encoding), b'('],
- ctx.out_string,
- [b');'],
- )
+ [self.callback_name.encode(out_string_encoding), b"("],
+ ctx.out_string,
+ [b");"],
+ )
class _SpyneJsonRpc1(JsonDocument):
version = 1
- VERSION = 'ver'
- BODY = 'body'
- HEAD = 'head'
- FAULT = 'fault'
+ VERSION = "ver"
+ BODY = "body"
+ HEAD = "head"
+ FAULT = "fault"
def decompose_incoming_envelope(self, ctx, message=JsonDocument.REQUEST):
indoc = ctx.in_document
@@ -304,12 +312,12 @@ def decompose_incoming_envelope(self, ctx, message=JsonDocument.REQUEST):
if not isinstance(ctx.in_header_doc, list):
ctx.in_header_doc = [ctx.in_header_doc]
- (ctx.method_request_string,ctx.in_body_doc), = body.items()
+ ((ctx.method_request_string, ctx.in_body_doc),) = body.items()
def deserialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_deserialize', ctx)
+ self.event_manager.fire_event("before_deserialize", ctx)
if ctx.descriptor is None:
raise ResourceNotFoundError(ctx.method_request_string)
@@ -328,13 +336,13 @@ def deserialize(self, ctx, message):
body_class = ctx.descriptor.out_message
# decode header objects
- if (ctx.in_header_doc is not None and header_class is not None):
+ if ctx.in_header_doc is not None and header_class is not None:
headers = [None] * len(header_class)
for i, (header_doc, head_class) in enumerate(
- zip(ctx.in_header_doc, header_class)):
+ zip(ctx.in_header_doc, header_class)
+ ):
if header_doc is not None and i < len(header_doc):
- headers[i] = self._doc_to_object(ctx, head_class,
- header_doc)
+ headers[i] = self._doc_to_object(ctx, head_class, header_doc)
if len(headers) == 1:
ctx.in_header = headers[0]
@@ -344,22 +352,20 @@ def deserialize(self, ctx, message):
if ctx.in_body_doc is None:
ctx.in_object = [None] * len(body_class._type_info)
else:
- ctx.in_object = self._doc_to_object(ctx, body_class,
- ctx.in_body_doc)
+ ctx.in_object = self._doc_to_object(ctx, body_class, ctx.in_body_doc)
- self.event_manager.fire_event('after_deserialize', ctx)
+ self.event_manager.fire_event("after_deserialize", ctx)
def serialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_serialize', ctx)
+ self.event_manager.fire_event("before_serialize", ctx)
ctx.out_document = {
"ver": self.version,
}
if ctx.out_error is not None:
- ctx.out_document[self.FAULT] = Fault.to_dict(Fault,
- ctx.out_error, self)
+ ctx.out_document[self.FAULT] = Fault.to_dict(Fault, ctx.out_error, self)
else:
if message is self.REQUEST:
@@ -389,8 +395,9 @@ def serialize(self, ctx, message):
out_object._safe_set(k, v, body_message_class, bm_attrs)
- ctx.out_document[self.BODY] = ctx.out_body_doc = \
- self._object_to_doc(body_message_class, out_object)
+ ctx.out_document[self.BODY] = ctx.out_body_doc = self._object_to_doc(
+ body_message_class, out_object
+ )
# header
if ctx.out_header is not None and header_message_class is not None:
@@ -401,25 +408,23 @@ def serialize(self, ctx, message):
ctx.out_header_doc = out_header_doc = []
- for header_class, out_header in zip(header_message_class,
- out_headers):
- out_header_doc.append(self._object_to_doc(header_class,
- out_header))
+ for header_class, out_header in zip(header_message_class, out_headers):
+ out_header_doc.append(self._object_to_doc(header_class, out_header))
if len(out_header_doc) > 1:
ctx.out_document[self.HEAD] = out_header_doc
else:
ctx.out_document[self.HEAD] = out_header_doc[0]
- self.event_manager.fire_event('after_serialize', ctx)
+ self.event_manager.fire_event("after_serialize", ctx)
+
+_json_rpc_flavors = {"spyne": _SpyneJsonRpc1}
-_json_rpc_flavors = {
- 'spyne': _SpyneJsonRpc1
-}
def JsonRpc(flavour, *args, **kwargs):
- assert flavour in _json_rpc_flavors, "Unknown JsonRpc flavor. " \
- "Accepted ones are: %r" % tuple(_json_rpc_flavors)
+ assert (
+ flavour in _json_rpc_flavors
+ ), "Unknown JsonRpc flavor. " "Accepted ones are: %r" % tuple(_json_rpc_flavors)
return _json_rpc_flavors[flavour](*args, **kwargs)
diff --git a/spyne/protocol/msgpack.py b/spyne/protocol/msgpack.py
index d30d59f22..aead93ed6 100644
--- a/spyne/protocol/msgpack.py
+++ b/spyne/protocol/msgpack.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -27,16 +26,23 @@
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
import msgpack
-from spyne import ValidationError
-from spyne.util import six
-from spyne.model.fault import Fault
-from spyne.model.primitive import Double
-from spyne.model.primitive import Boolean
-from spyne.model.primitive import Integer
+from spyne.model.enum import EnumBase
+from spyne.model.fault import Fault, ValidationError
+from spyne.model.primitive import (
+ Boolean,
+ Date,
+ DateTime,
+ Double,
+ Duration,
+ Integer,
+ Time,
+ Unicode,
+)
from spyne.protocol.dictdoc import HierDictDocument
@@ -44,23 +50,22 @@ class MessagePackDecodeError(Fault):
CODE = "Client.MessagePackDecodeError"
def __init__(self, data=None):
- super(MessagePackDecodeError, self) \
- .__init__(self.CODE, data)
+ super(MessagePackDecodeError, self).__init__(self.CODE, data)
-NON_NUMBER_TYPES = tuple({list, dict, six.text_type, six.binary_type})
+NON_NUMBER_TYPES = tuple({list, dict, str, bytes})
class MessagePackDocument(HierDictDocument):
"""An integration class for the msgpack protocol."""
- mime_type = 'application/x-msgpack'
+ mime_type = "application/x-msgpack"
text_based = False
type = set(HierDictDocument.type)
- type.add('msgpack')
+ type.add("msgpack")
- default_string_encoding = 'UTF-8'
+ default_string_encoding = "UTF-8"
from_serstr = HierDictDocument.from_bytes
to_serstr = HierDictDocument.to_bytes
@@ -68,41 +73,62 @@ class MessagePackDocument(HierDictDocument):
_decimal_as_string = True
_huge_numbers_as_string = True
- def __init__(self, app=None, validator=None, mime_type=None,
- ignore_uncap=False,
- # DictDocument specific
- ignore_wrappers=True,
- complex_as=dict,
- ordered=False,
- polymorphic=False,
- key_encoding='utf8',
- # MessagePackDocument specific
- mw_packer=msgpack.Packer,
- mw_unpacker=msgpack.Unpacker,
- use_list=False,
- raw=False,
- use_bin_type=True,
- **kwargs):
- super(MessagePackDocument, self).__init__(app, validator, mime_type,
- ignore_uncap, ignore_wrappers, complex_as, ordered, polymorphic,
- key_encoding)
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ mime_type=None,
+ ignore_uncap=False,
+ # DictDocument specific
+ ignore_wrappers=True,
+ complex_as=dict,
+ ordered=False,
+ polymorphic=False,
+ key_encoding="utf8",
+ # MessagePackDocument specific
+ mw_packer=msgpack.Packer,
+ mw_unpacker=msgpack.Unpacker,
+ use_list=False,
+ raw=False,
+ use_bin_type=True,
+ **kwargs,
+ ):
+ super(MessagePackDocument, self).__init__(
+ app,
+ validator,
+ mime_type,
+ ignore_uncap,
+ ignore_wrappers,
+ complex_as,
+ ordered,
+ polymorphic,
+ key_encoding,
+ )
self.mw_packer = mw_packer
self.mw_unpacker = mw_unpacker
- # unpacker
+ # unpacker / packer string handling
if not raw:
self.from_serstr = self.from_unicode
if use_bin_type:
self.from_serstr = self.from_unicode
+ # with use_bin_type=True, bytes are binary; text types must stay as
+ # Python str so msgpack encodes them as str type (fixstr/str8)
+ self._to_bytes_handlers[Unicode] = self.unicode_to_unicode
+ self._to_unicode_handlers[Unicode] = self.unicode_to_unicode
+ self._to_bytes_handlers[Date] = self.date_to_unicode
+ self._to_bytes_handlers[DateTime] = self.datetime_to_unicode
+ self._to_bytes_handlers[Time] = self.time_to_unicode
+ self._to_bytes_handlers[Duration] = self.duration_to_unicode
+ self._to_bytes_handlers[EnumBase] = self.model_base_to_unicode
self.kwargs_packer = dict(kwargs)
self.kwargs_unpacker = dict(kwargs)
- self.kwargs_packer['raw'] = self.kwargs_unpacker['raw'] = raw
- self.kwargs_packer['use_list'] = self.kwargs_unpacker['use_list'] \
- = use_list
- self.kwargs_packer['use_bin_type'] = use_bin_type
+ self.kwargs_packer["raw"] = self.kwargs_unpacker["raw"] = raw
+ self.kwargs_packer["use_list"] = self.kwargs_unpacker["use_list"] = use_list
+ self.kwargs_packer["use_bin_type"] = use_bin_type
self._from_bytes_handlers[Double] = self._ret_number
self._from_bytes_handlers[Boolean] = self._ret_bool
@@ -137,10 +163,12 @@ def _ret_bool(self, _, value):
def get_class_name(self, cls):
class_name = cls.get_type_name()
- if not six.PY2:
+ if self.kwargs_unpacker.get("raw", False):
if not isinstance(class_name, bytes):
class_name = class_name.encode(self.default_string_encoding)
-
+ else:
+ if isinstance(class_name, bytes):
+ class_name = class_name.decode("utf8")
return class_name
def create_in_document(self, ctx, in_string_encoding=None):
@@ -153,18 +181,20 @@ def create_in_document(self, ctx, in_string_encoding=None):
# handle mmap objects from in ctx.in_string as returned by
# TwistedWebResource.handle_rpc.
- if isinstance(ctx.in_string, (list, tuple)) \
- and len(ctx.in_string) == 1 \
- and isinstance(ctx.in_string[0], memoryview):
+ if (
+ isinstance(ctx.in_string, (list, tuple))
+ and len(ctx.in_string) == 1
+ and isinstance(ctx.in_string[0], memoryview)
+ ):
unpacker = self.mw_unpacker(**self.kwargs_unpacker)
unpacker.feed(ctx.in_string[0])
ctx.in_document = next(x for x in unpacker)
else:
try:
- ctx.in_document = msgpack.unpackb(b''.join(ctx.in_string))
+ ctx.in_document = msgpack.unpackb(b"".join(ctx.in_string))
except ValueError as e:
- raise MessagePackDecodeError(' '.join(e.args))
+ raise MessagePackDecodeError(" ".join(e.args))
def gen_method_request_string(self, ctx):
"""Uses information in context object to return a method_request_string.
@@ -172,24 +202,23 @@ def gen_method_request_string(self, ctx):
Returns a string in the form of "{namespaces}method name".
"""
- mrs, = ctx.in_body_doc.keys()
- if not six.PY2 and isinstance(mrs, bytes):
+ (mrs,) = ctx.in_body_doc.keys()
+ if isinstance(mrs, bytes):
mrs = mrs.decode(self.key_encoding)
- return '{%s}%s' % (self.app.interface.get_tns(), mrs)
+ return "{%s}%s" % (self.app.interface.get_tns(), mrs)
- def create_out_string(self, ctx, out_string_encoding='utf8'):
+ def create_out_string(self, ctx, out_string_encoding="utf8"):
ctx.out_string = (msgpack.packb(o) for o in ctx.out_document)
def integer_from_bytes(self, cls, value):
- if isinstance(value, (six.text_type, six.binary_type)):
- return super(MessagePackDocument, self) \
- .integer_from_bytes(cls, value)
+ if isinstance(value, (str, bytes)):
+ return super(MessagePackDocument, self).integer_from_bytes(cls, value)
return value
def integer_to_bytes(self, cls, value, **_):
# if it's inside the range msgpack can deal with
- if -1<<63 <= value < 1<<64:
+ if -1 << 63 <= value < 1 << 64:
return value
else:
return super(MessagePackDocument, self).integer_to_bytes(cls, value)
@@ -198,14 +227,14 @@ def integer_to_bytes(self, cls, value, **_):
class MessagePackRpc(MessagePackDocument):
"""An integration class for the msgpack-rpc protocol."""
- mime_type = 'application/x-msgpack'
+ mime_type = "application/x-msgpack"
MSGPACK_REQUEST = 0
MSGPACK_RESPONSE = 1
MSGPACK_NOTIFY = 2
MSGPACK_ERROR = 3
- def create_out_string(self, ctx, out_string_encoding='utf8'):
+ def create_out_string(self, ctx, out_string_encoding="utf8"):
ctx.out_string = (msgpack.packb(o) for o in ctx.out_document)
def create_in_document(self, ctx, in_string_encoding=None):
@@ -218,12 +247,12 @@ def create_in_document(self, ctx, in_string_encoding=None):
# TODO: Use feed api
try:
- ctx.in_document = msgpack.unpackb(b''.join(ctx.in_string),
- **self.kwargs_unpacker)
-
+ ctx.in_document = msgpack.unpackb(
+ b"".join(ctx.in_string), **self.kwargs_unpacker
+ )
except ValueError as e:
- raise MessagePackDecodeError(''.join(e.args))
+ raise MessagePackDecodeError("".join(e.args))
try:
len(ctx.in_document)
@@ -231,8 +260,9 @@ def create_in_document(self, ctx, in_string_encoding=None):
raise MessagePackDecodeError("Input must be a sequence.")
if not (3 <= len(ctx.in_document) <= 4):
- raise MessagePackDecodeError("Length of input iterable must be "
- "either 3 or 4")
+ raise MessagePackDecodeError(
+ "Length of input iterable must be " "either 3 or 4"
+ )
def decompose_incoming_envelope(self, ctx, message):
# FIXME: For example: {0: 0, 1: 0, 2: "some_call", 3: [1,2,3]} will also
@@ -246,10 +276,8 @@ def decompose_incoming_envelope(self, ctx, message):
else:
msgtype, msgid, msgname_or_error, msgparams = ctx.in_document
- if not six.PY2:
- if isinstance(msgname_or_error, bytes):
- msgname_or_error = msgname_or_error.decode(
- self.default_string_encoding)
+ if isinstance(msgname_or_error, bytes):
+ msgname_or_error = msgname_or_error.decode(self.default_string_encoding)
if msgtype == MessagePackRpc.MSGPACK_REQUEST:
assert message == MessagePackRpc.REQUEST
@@ -260,11 +288,16 @@ def decompose_incoming_envelope(self, ctx, message):
elif msgtype == MessagePackRpc.MSGPACK_NOTIFY:
raise NotImplementedError()
+ elif msgtype == MessagePackRpc.MSGPACK_ERROR:
+ assert message == MessagePackRpc.RESPONSE
+
else:
raise MessagePackDecodeError("Unknown message type %r" % msgtype)
- ctx.method_request_string = '{%s}%s' % (self.app.interface.get_tns(),
- msgname_or_error)
+ ctx.method_request_string = "{%s}%s" % (
+ self.app.interface.get_tns(),
+ msgname_or_error,
+ )
# MessagePackRpc does not seem to have Header support
ctx.in_header_doc = None
@@ -281,11 +314,10 @@ def decompose_incoming_envelope(self, ctx, message):
def deserialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_deserialize', ctx)
+ self.event_manager.fire_event("before_deserialize", ctx)
if ctx.descriptor is None:
- raise Fault("Client", "Method %r not found." %
- ctx.method_request_string)
+ raise Fault("Client", "Method %r not found." % ctx.method_request_string)
# instantiate the result message
if message is self.REQUEST:
@@ -299,23 +331,27 @@ def deserialize(self, ctx, message):
ctx.in_error = Fault(**ctx.in_error)
elif body_class:
- ctx.in_object = self._doc_to_object(ctx,
- body_class, ctx.in_body_doc, self.validator)
+ ctx.in_object = self._doc_to_object(
+ ctx, body_class, ctx.in_body_doc, self.validator
+ )
else:
ctx.in_object = []
- self.event_manager.fire_event('after_deserialize', ctx)
+ self.event_manager.fire_event("after_deserialize", ctx)
def serialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_serialize', ctx)
+ self.event_manager.fire_event("before_serialize", ctx)
if ctx.out_error is not None:
ctx.out_document = [
- [MessagePackRpc.MSGPACK_ERROR, 0,
- Fault.to_dict(ctx.out_error.__class__, ctx.out_error, self)]
+ [
+ MessagePackRpc.MSGPACK_ERROR,
+ 0,
+ Fault.to_dict(ctx.out_error.__class__, ctx.out_error, self),
+ ]
]
return
@@ -348,11 +384,12 @@ def serialize(self, ctx, message):
# transform the results into a dict:
if out_type.Attributes.max_occurs > 1:
- params = (self._to_dict_value(out_type, inst, set())
- for inst in out_instance)
+ params = (
+ self._to_dict_value(out_type, inst, set()) for inst in out_instance
+ )
else:
params = self._to_dict_value(out_type, out_instance, set())
ctx.out_document = [[msgtype, 0, method_name_or_error, params]]
- self.event_manager.fire_event('after_serialize', ctx)
+ self.event_manager.fire_event("after_serialize", ctx)
diff --git a/spyne/protocol/soap/__init__.py b/spyne/protocol/soap/__init__.py
index 754461f3e..0cd166cb4 100644
--- a/spyne/protocol/soap/__init__.py
+++ b/spyne/protocol/soap/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -24,7 +23,5 @@
Patches are welcome.
"""
-from spyne.protocol.soap.soap11 import Soap11
-from spyne.protocol.soap.soap11 import _from_soap
-from spyne.protocol.soap.soap11 import _parse_xml_string
-from spyne.protocol.soap.soap12 import Soap12
\ No newline at end of file
+from spyne.protocol.soap.soap11 import Soap11, _from_soap, _parse_xml_string
+from spyne.protocol.soap.soap12 import Soap12
diff --git a/spyne/protocol/soap/mime.py b/spyne/protocol/soap/mime.py
index 90b536020..abd7bbd84 100644
--- a/spyne/protocol/soap/mime.py
+++ b/spyne/protocol/soap/mime.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -29,30 +28,22 @@
from __future__ import print_function, unicode_literals
import logging
+
logger = logging.getLogger(__name__)
import re
-
from base64 import b64encode
+from email import generator, message_from_bytes
+from email.encoders import encode_7or8bit
+from email.mime.application import MIMEApplication
+from email.mime.multipart import MIMEMultipart
from itertools import chain
from lxml import etree
-from email import generator
-from email.mime.multipart import MIMEMultipart
-from email.mime.application import MIMEApplication
-from email.encoders import encode_7or8bit
-
-from spyne import ValidationError
-from spyne.util import six
-from spyne.model.binary import ByteArray, File
from spyne.const.xml import NS_XOP
-
-if six.PY2:
- from email import message_from_string as message_from_bytes
-else:
- from email import message_from_bytes
-
+from spyne.model.binary import ByteArray, File
+from spyne.model.fault import ValidationError
XPATH_NSDICT = dict(xop=NS_XOP)
@@ -84,14 +75,17 @@ def _join_attachment(ns_soap_env, href_id, envelope, payload, prefix=True):
message = child
break
- idprefix = ''
+ idprefix = ""
if prefix:
idprefix = "cid:"
- href_id = "%s%s" % (idprefix, href_id,)
+ href_id = "%s%s" % (
+ idprefix,
+ href_id,
+ )
num = 0
- xpath = ".//xop:Include[@href=\"{}\"]".format(href_id)
+ xpath = './/xop:Include[@href="{}"]'.format(href_id)
for num, node in enumerate(message.xpath(xpath, namespaces=XPATH_NSDICT)):
parent = node.getparent()
@@ -122,53 +116,54 @@ def collapse_swa(ctx, content_type, ns_soap_env):
envelope = ctx.in_string
# convert multipart messages back to pure SOAP
mime_type, content_data = content_type
- if not six.PY2:
- assert isinstance(mime_type, six.text_type)
+ assert isinstance(mime_type, str)
- if u'multipart/related' not in mime_type:
+ if "multipart/related" not in mime_type:
return envelope
- charset = content_data.get('charset', None)
+ charset = content_data.get("charset", None)
if charset is None:
- charset = 'ascii'
+ charset = "ascii"
- boundary = content_data.get('boundary', None)
+ boundary = content_data.get("boundary", None)
if boundary is None:
- raise ValidationError(None, u"Missing 'boundary' value from "
- u"Content-Type header")
+ raise ValidationError(
+ None, "Missing 'boundary' value from " "Content-Type header"
+ )
envelope = list(envelope)
# What an ugly hack...
- request = MIMEMultipart('related', boundary=boundary)
- msg_string = re.sub(r"\n\n.*", '', request.as_string())
+ request = MIMEMultipart("related", boundary=boundary)
+ msg_string = re.sub(r"\n\n.*", "", request.as_string())
msg_string = chain(
- (msg_string.encode(charset), generator.NL.encode('ascii')),
+ (msg_string.encode(charset), generator.NL.encode("ascii")),
(e for e in envelope),
)
- msg_string = b''.join(msg_string)
+ msg_string = b"".join(msg_string)
msg = message_from_bytes(msg_string) # our message
soapmsg = None
- root = msg.get_param('start')
+ root = msg.get_param("start")
# walk through sections, reconstructing pure SOAP
for part in msg.walk():
# skip the multipart container section
- if part.get_content_maintype() == 'multipart':
+ if part.get_content_maintype() == "multipart":
continue
# detect main soap section
- if (part.get('Content-ID') and part.get('Content-ID') == root) or \
- (root is None and part == msg.get_payload()[0]):
+ if (part.get("Content-ID") and part.get("Content-ID") == root) or (
+ root is None and part == msg.get_payload()[0]
+ ):
soapmsg = part.get_payload()
continue
# binary packages
cte = part.get("Content-Transfer-Encoding")
- if cte != 'base64':
+ if cte != "base64":
payload = b64encode(part.get_payload(decode=True))
else:
payload = part.get_payload()
@@ -179,14 +174,13 @@ def collapse_swa(ctx, content_type, ns_soap_env):
# Check for Content-ID and make replacement
if cid:
- soapmsg, numreplaces = _join_attachment(
- ns_soap_env, cid, soapmsg, payload)
+ soapmsg, numreplaces = _join_attachment(ns_soap_env, cid, soapmsg, payload)
# Check for Content-Location and make replacement
if cloc and not cid and not numreplaces:
soapmsg, numreplaces = _join_attachment(
- ns_soap_env, cloc, soapmsg, payload,
- False)
+ ns_soap_env, cloc, soapmsg, payload, False
+ )
if soapmsg is None:
raise ValidationError(None, "Invalid MtoM request")
@@ -215,7 +209,7 @@ def apply_mtom(headers, envelope, params, paramvals):
"""
# grab the XML element of the message in the SOAP body
- envelope = ''.join(envelope)
+ envelope = "".join(envelope)
soaptree = etree.fromstring(envelope)
soapbody = soaptree.find("{%s}Body" % _ns_soap_env)
@@ -231,36 +225,36 @@ def apply_mtom(headers, envelope, params, paramvals):
# Get additional parameters from original Content-Type
ctarray = []
for n, v in headers.items():
- if n.lower() == 'content-type':
- ctarray = v.split(';')
+ if n.lower() == "content-type":
+ ctarray = v.split(";")
break
roottype = ctarray[0].strip()
rootparams = {}
for ctparam in ctarray[1:]:
- n, v = ctparam.strip().split('=')
+ n, v = ctparam.strip().split("=")
rootparams[n] = v.strip("\"'")
# Set up initial MIME parts.
- mtompkg = MIMEMultipart('related', boundary='?//<><>spyne_MIME_boundary<>')
- rootpkg = MIMEApplication(envelope, 'xop+xml', encode_7or8bit)
+ mtompkg = MIMEMultipart("related", boundary="?//<><>spyne_MIME_boundary<>")
+ rootpkg = MIMEApplication(envelope, "xop+xml", encode_7or8bit)
# Set up multipart headers.
- del mtompkg['mime-version']
- mtompkg.set_param('start-info', roottype)
- mtompkg.set_param('start', '')
- if 'SOAPAction' in headers:
- mtompkg.add_header('SOAPAction', headers.get('SOAPAction'))
+ del mtompkg["mime-version"]
+ mtompkg.set_param("start-info", roottype)
+ mtompkg.set_param("start", "")
+ if "SOAPAction" in headers:
+ mtompkg.add_header("SOAPAction", headers.get("SOAPAction"))
# Set up root SOAP part headers.
- del rootpkg['mime-version']
+ del rootpkg["mime-version"]
- rootpkg.add_header('Content-ID', '')
+ rootpkg.add_header("Content-ID", "")
for n, v in rootparams.items():
rootpkg.set_param(n, v)
- rootpkg.set_param('type', roottype)
+ rootpkg.set_param("type", roottype)
mtompkg.attach(rootpkg)
@@ -269,7 +263,7 @@ def apply_mtom(headers, envelope, params, paramvals):
name, typ = params[i]
if issubclass(typ, (ByteArray, File)):
- id = "SpyneAttachment_%s" % (len(mtompkg.get_payload()), )
+ id = "SpyneAttachment_%s" % (len(mtompkg.get_payload()),)
param = message[i]
param.text = ""
@@ -283,20 +277,20 @@ def apply_mtom(headers, envelope, params, paramvals):
if issubclass(type, File):
data = paramvals[i].data
else:
- data = ''.join(paramvals[i])
+ data = "".join(paramvals[i])
attachment = MIMEApplication(data, _encoder=encode_7or8bit)
- del attachment['mime-version']
+ del attachment["mime-version"]
- attachment.add_header('Content-ID', '<%s>' % (id, ))
+ attachment.add_header("Content-ID", "<%s>" % (id,))
mtompkg.attach(attachment)
# Update SOAP envelope.
rootpkg.set_payload(etree.tostring(soaptree))
# extract body string from MIMEMultipart message
- bound = '--%s' % (mtompkg.get_boundary(), )
+ bound = "--%s" % (mtompkg.get_boundary(),)
marray = mtompkg.as_string().split(bound)
mtombody = bound
mtombody += bound.join(marray[1:])
diff --git a/spyne/protocol/soap/soap11.py b/spyne/protocol/soap/soap11.py
index 21a02b890..7dc33a787 100644
--- a/spyne/protocol/soap/soap11.py
+++ b/spyne/protocol/soap/soap11.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -35,49 +34,43 @@
""" % (__name__, __name__ + ".invalid")
import logging
+
logger = logging.getLogger(__name__)
logger_invalid = logging.getLogger(__name__ + ".invalid")
from itertools import chain
-import spyne.const.xml as ns
-
from lxml import etree
-from lxml.etree import XMLSyntaxError
-from lxml.etree import XMLParser
+from lxml.etree import XMLParser, XMLSyntaxError
-from spyne import BODY_STYLE_WRAPPED
-from spyne.util import six
-from spyne.util.http import parse_content_type_header
-from spyne.const.xml import DEFAULT_NS
+import spyne.const.xml as ns
from spyne.const.http import HTTP_405, HTTP_500
+from spyne.const.xml import DEFAULT_NS
+from spyne.descriptor import BODY_STYLE_WRAPPED
from spyne.error import RequestNotAllowed
from spyne.model.fault import Fault
-from spyne.model.primitive import Date, Time, DateTime
-from spyne.protocol.xml import XmlDocument
+from spyne.model.primitive import Date, DateTime, Time
from spyne.protocol.soap.mime import collapse_swa
+from spyne.protocol.xml import XmlDocument
from spyne.server.http import HttpTransportContext
+from spyne.util.http import parse_content_type_header
def _from_soap(in_envelope_xml, xmlids=None, **kwargs):
- """Parses the xml string into the header and payload.
- """
- ns_soap = kwargs.pop('ns', ns.NS_SOAP11_ENV)
+ """Parses the xml string into the header and payload."""
+ ns_soap = kwargs.pop("ns", ns.NS_SOAP11_ENV)
if xmlids:
resolve_hrefs(in_envelope_xml, xmlids)
- if in_envelope_xml.tag != '{%s}Envelope' % ns_soap:
- raise Fault('Client.SoapError', 'No {%s}Envelope element was found!' %
- ns_soap)
+ if in_envelope_xml.tag != "{%s}Envelope" % ns_soap:
+ raise Fault("Client.SoapError", "No {%s}Envelope element was found!" % ns_soap)
- header_envelope = in_envelope_xml.xpath('e:Header',
- namespaces={'e': ns_soap})
- body_envelope = in_envelope_xml.xpath('e:Body',
- namespaces={'e': ns_soap})
+ header_envelope = in_envelope_xml.xpath("e:Header", namespaces={"e": ns_soap})
+ body_envelope = in_envelope_xml.xpath("e:Body", namespaces={"e": ns_soap})
if len(header_envelope) == 0 and len(body_envelope) == 0:
- raise Fault('Client.SoapError', 'Soap envelope is empty!')
+ raise Fault("Client.SoapError", "Soap envelope is empty!")
header = None
if len(header_envelope) > 0:
@@ -93,10 +86,10 @@ def _from_soap(in_envelope_xml, xmlids=None, **kwargs):
def _parse_xml_string(xml_string, parser, charset=None):
xml_string = iter(xml_string)
chunk = next(xml_string)
- if isinstance(chunk, six.binary_type):
- string = b''.join(chain( (chunk,), xml_string ))
+ if isinstance(chunk, bytes):
+ string = b"".join(chain((chunk,), xml_string))
else:
- string = ''.join(chain( (chunk,), xml_string ))
+ string = "".join(chain((chunk,), xml_string))
if charset:
string = string.decode(charset)
@@ -106,13 +99,15 @@ def _parse_xml_string(xml_string, parser, charset=None):
root, xmlids = etree.XMLID(string, parser)
except ValueError as e:
- logger.debug('ValueError: Deserializing from unicode strings with '
- 'encoding declaration is not supported by lxml.')
+ logger.debug(
+ "ValueError: Deserializing from unicode strings with "
+ "encoding declaration is not supported by lxml."
+ )
root, xmlids = etree.XMLID(string.encode(charset), parser)
except XMLSyntaxError as e:
logger_invalid.error("%r in string %r", e, string)
- raise Fault('Client.XMLSyntaxError', str(e))
+ raise Fault("Client.XMLSyntaxError", str(e))
return root, xmlids
@@ -121,11 +116,11 @@ def _parse_xml_string(xml_string, parser, charset=None):
# section 5.2.1 for an example of how the id and href attributes are used.
def resolve_hrefs(element, xmlids):
for e in element:
- if e.get('id'):
- continue # don't need to resolve this element
+ if e.get("id"):
+ continue # don't need to resolve this element
- elif e.get('href'):
- resolved_element = xmlids[e.get('href').replace('#', '')]
+ elif e.get("href"):
+ resolved_element = xmlids[e.get("href").replace("#", "")]
if resolved_element is None:
continue
resolve_hrefs(resolved_element, xmlids)
@@ -164,10 +159,10 @@ class Soap11(XmlDocument):
format.
"""
- mime_type = 'text/xml; charset=utf-8'
+ mime_type = "text/xml; charset=utf-8"
type = set(XmlDocument.type)
- type.update(('soap', 'soap11'))
+ type.update(("soap", "soap11"))
ns_soap_env = ns.NS_SOAP11_ENV
ns_soap_enc = ns.NS_SOAP11_ENC
@@ -193,24 +188,26 @@ def create_in_document(self, ctx, charset=None):
if content_type is None or http_verb != "POST":
ctx.transport.resp_code = HTTP_405
raise RequestNotAllowed(
- "You must issue a POST request with the Content-Type "
- "header properly set.")
+ "You must issue a POST request with the Content-Type "
+ "header properly set."
+ )
content_type = parse_content_type_header(content_type)
ctx.in_string = collapse_swa(ctx, content_type, self.ns_soap_env)
- ctx.in_document = _parse_xml_string(ctx.in_string,
- XMLParser(**self.parser_kwargs),
- charset)
+ ctx.in_document = _parse_xml_string(
+ ctx.in_string, XMLParser(**self.parser_kwargs), charset
+ )
def decompose_incoming_envelope(self, ctx, message=XmlDocument.REQUEST):
envelope_xml, xmlids = ctx.in_document
- header_document, body_document = _from_soap(envelope_xml, xmlids,
- ns=self.ns_soap_env)
+ header_document, body_document = _from_soap(
+ envelope_xml, xmlids, ns=self.ns_soap_env
+ )
ctx.in_document = envelope_xml
- if body_document.tag == '{%s}Fault' % self.ns_soap_env:
+ if body_document.tag == "{%s}Fault" % self.ns_soap_env:
ctx.in_body_doc = body_document
else:
@@ -229,7 +226,7 @@ def deserialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_deserialize', ctx)
+ self.event_manager.fire_event("before_deserialize", ctx)
if ctx.in_body_doc.tag == "{%s}Fault" % self.ns_soap_env:
ctx.in_object = None
@@ -246,18 +243,20 @@ def deserialize(self, ctx, message):
# decode header objects
# header elements are returned in header_class order which need not match the incoming XML
- if (ctx.in_header_doc is not None and header_class is not None):
+ if ctx.in_header_doc is not None and header_class is not None:
headers = [None] * len(header_class)
- in_header_dict = dict( [(element.tag, element)
- for element in ctx.in_header_doc])
+ in_header_dict = dict(
+ [(element.tag, element) for element in ctx.in_header_doc]
+ )
for i, head_class in enumerate(header_class):
if i < len(header_class):
- nsval = "{%s}%s" % (head_class.__namespace__,
- head_class.__type_name__)
+ nsval = "{%s}%s" % (
+ head_class.__namespace__,
+ head_class.__type_name__,
+ )
header_doc = in_header_dict.get(nsval, None)
if header_doc is not None:
- headers[i] = self.from_element(ctx, head_class,
- header_doc)
+ headers[i] = self.from_element(ctx, head_class, header_doc)
if len(headers) == 1:
ctx.in_header = headers[0]
@@ -268,10 +267,9 @@ def deserialize(self, ctx, message):
if ctx.in_body_doc is None:
ctx.in_object = [None] * len(body_class._type_info)
else:
- ctx.in_object = self.from_element(ctx, body_class,
- ctx.in_body_doc)
+ ctx.in_object = self.from_element(ctx, body_class, ctx.in_body_doc)
- self.event_manager.fire_event('after_deserialize', ctx)
+ self.event_manager.fire_event("after_deserialize", ctx)
def serialize(self, ctx, message):
"""Uses ctx.out_object, ctx.out_header or ctx.out_error to set
@@ -283,18 +281,23 @@ def serialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_serialize', ctx)
+ self.event_manager.fire_event("before_serialize", ctx)
# construct the soap response, and serialize it
nsmap = self.app.interface.nsmap
- ctx.out_document = etree.Element('{%s}Envelope' % self.ns_soap_env,
- nsmap=nsmap)
+ ctx.out_document = etree.Element("{%s}Envelope" % self.ns_soap_env, nsmap=nsmap)
if ctx.out_error is not None:
# FIXME: There's no way to alter soap response headers for the user.
- ctx.out_body_doc = out_body_doc = etree.SubElement(ctx.out_document,
- '{%s}Body' % self.ns_soap_env, nsmap=nsmap)
- self.to_parent(ctx, ctx.out_error.__class__, ctx.out_error,
- out_body_doc, self.app.interface.get_tns())
+ ctx.out_body_doc = out_body_doc = etree.SubElement(
+ ctx.out_document, "{%s}Body" % self.ns_soap_env, nsmap=nsmap
+ )
+ self.to_parent(
+ ctx,
+ ctx.out_error.__class__,
+ ctx.out_error,
+ out_body_doc,
+ self.app.interface.get_tns(),
+ )
else:
if message is self.REQUEST:
@@ -307,7 +310,8 @@ def serialize(self, ctx, message):
# body
ctx.out_body_doc = out_body_doc = etree.Element(
- '{%s}Body' % self.ns_soap_env)
+ "{%s}Body" % self.ns_soap_env
+ )
# assign raw result to its wrapper, result_message
if ctx.descriptor.body_style is BODY_STYLE_WRAPPED:
@@ -329,8 +333,13 @@ def serialize(self, ctx, message):
out_object._safe_set(k, v, body_message_class, bm_attrs)
- self.to_parent(ctx, body_message_class, out_object,
- out_body_doc, body_message_class.get_namespace())
+ self.to_parent(
+ ctx,
+ body_message_class,
+ out_object,
+ out_body_doc,
+ body_message_class.get_namespace(),
+ )
else:
out_object = ctx.out_object[0]
@@ -345,23 +354,26 @@ def serialize(self, ctx, message):
if sub_name is None:
sub_name = body_message_class.get_type_name()
- self.to_parent(ctx, body_message_class, out_object, out_body_doc,
- sub_ns, sub_name)
+ self.to_parent(
+ ctx, body_message_class, out_object, out_body_doc, sub_ns, sub_name
+ )
# header
if ctx.out_header is not None and header_message_class is not None:
ctx.out_header_doc = soap_header_elt = etree.SubElement(
- ctx.out_document, '{%s}Header' % self.ns_soap_env)
+ ctx.out_document, "{%s}Header" % self.ns_soap_env
+ )
if isinstance(ctx.out_header, (list, tuple)):
out_headers = ctx.out_header
else:
out_headers = (ctx.out_header,)
- for header_class, out_header in zip(header_message_class,
- out_headers):
- self.to_parent(ctx,
- header_class, out_header,
+ for header_class, out_header in zip(header_message_class, out_headers):
+ self.to_parent(
+ ctx,
+ header_class,
+ out_header,
soap_header_elt,
header_class.get_namespace(),
header_class.get_type_name(),
@@ -372,7 +384,7 @@ def serialize(self, ctx, message):
if self.cleanup_namespaces:
etree.cleanup_namespaces(ctx.out_document)
- self.event_manager.fire_event('after_serialize', ctx)
+ self.event_manager.fire_event("after_serialize", ctx)
def fault_to_http_response_code(self, fault):
return HTTP_500
diff --git a/spyne/protocol/soap/soap12.py b/spyne/protocol/soap/soap12.py
index 53e656a69..59280a02f 100644
--- a/spyne/protocol/soap/soap12.py
+++ b/spyne/protocol/soap/soap12.py
@@ -28,12 +28,10 @@
from lxml.builder import E
+from spyne.const.xml import NS_SOAP12_ENV, NS_XML, PREFMAP
from spyne.protocol.soap.soap11 import Soap11
from spyne.protocol.xml import _append
-from spyne.util.six import string_types
from spyne.util.etreeconv import root_dict_to_etree
-from spyne.const.xml import NS_SOAP12_ENV, NS_XML, PREFMAP
-
logger = logging.getLogger(__name__)
logger_invalid = logging.getLogger(__name__ + ".invalid")
@@ -44,49 +42,55 @@ class Soap12(Soap11):
The base implementation of a subset of the Soap 1.2 standard. The
document is available here: http://www.w3.org/TR/soap12/
"""
- mime_type = 'application/soap+xml; charset=utf-8'
+
+ mime_type = "application/soap+xml; charset=utf-8"
soap_env = PREFMAP[NS_SOAP12_ENV]
ns_soap_env = NS_SOAP12_ENV
type = set(Soap11.type)
- type.discard('soap11')
- type.update(('soap', 'soap12'))
+ type.discard("soap11")
+ type.update(("soap", "soap12"))
def generate_subcode(self, value, subcode=None):
subcode_node = E("{%s}Subcode" % self.ns_soap_env)
subcode_node.append(E("{%s}Value" % self.ns_soap_env, value))
- if subcode:
+ if subcode is not None:
subcode_node.append(subcode)
return subcode_node
def gen_fault_codes(self, faultstring):
- faultstrings = faultstring.split('.')
+ faultstrings = faultstring.split(".")
value = faultstrings.pop(0)
- if value == 'Client':
- value = '%s:Sender' % self.soap_env
- elif value == 'Server':
- value = '%s:Receiver' % self.soap_env
+ if value == "Client":
+ value = "%s:Sender" % self.soap_env
+ elif value == "Server":
+ value = "%s:Receiver" % self.soap_env
else:
- raise TypeError('Wrong fault code, got', type(faultstring))
+ raise TypeError("Wrong fault code, got", type(faultstring))
return value, faultstrings
def generate_faultcode(self, element):
nsmap = element.nsmap
faultcode = []
- faultcode.append(element.find('soap:Code/soap:Value', namespaces=nsmap).text)
- subcode = element.find('soap:Code/soap:Subcode', namespaces=nsmap)
+ faultcode.append(element.find("soap:Code/soap:Value", namespaces=nsmap).text)
+ subcode = element.find("soap:Code/soap:Subcode", namespaces=nsmap)
while subcode is not None:
- faultcode.append(subcode.find('soap:Value', namespaces=nsmap).text)
- subcode = subcode.find('soap:Subcode', namespaces=nsmap)
+ faultcode.append(subcode.find("soap:Value", namespaces=nsmap).text)
+ subcode = subcode.find("soap:Subcode", namespaces=nsmap)
- return '.'.join(faultcode)
+ return ".".join(faultcode)
def fault_to_parent(self, ctx, cls, inst, parent, ns, **_):
reason = E("{%s}Reason" % self.ns_soap_env)
- reason.append(E("{%s}Text" % self.ns_soap_env, inst.faultstring,
- **{'{%s}lang' % NS_XML: inst.lang}))
+ reason.append(
+ E(
+ "{%s}Text" % self.ns_soap_env,
+ inst.faultstring,
+ **{"{%s}lang" % NS_XML: inst.lang},
+ )
+ )
subelts = [
None, # The code tag is put here down the road
@@ -101,15 +105,15 @@ def _fault_to_parent_impl(self, ctx, cls, inst, parent, ns, subelts, **_):
tag_name = "{%s}Fault" % self.ns_soap_env
- if isinstance(inst.faultcode, string_types):
+ if isinstance(inst.faultcode, str):
value, faultcodes = self.gen_fault_codes(inst.faultcode)
code = E("{%s}Code" % self.ns_soap_env)
code.append(E("{%s}Value" % self.ns_soap_env, value))
- child_subcode = False
+ child_subcode = None
for value in faultcodes[::-1]:
- if child_subcode:
+ if child_subcode is not None:
child_subcode = self.generate_subcode(value, child_subcode)
else:
child_subcode = self.generate_subcode(value)
@@ -120,17 +124,20 @@ def _fault_to_parent_impl(self, ctx, cls, inst, parent, ns, subelts, **_):
subelts[0] = code
if isinstance(inst.detail, dict):
- _append(subelts, E('{%s}Detail' % self.ns_soap_env,
- root_dict_to_etree(inst.detail)))
+ _append(
+ subelts,
+ E("{%s}Detail" % self.ns_soap_env, root_dict_to_etree(inst.detail)),
+ )
elif inst.detail is None:
pass
else:
- raise TypeError('Fault detail Must be dict, got', type(inst.detail))
+ raise TypeError("Fault detail Must be dict, got", type(inst.detail))
- return self.gen_members_parent(ctx, cls, inst, parent, tag_name,
- subelts, add_type=False)
+ return self.gen_members_parent(
+ ctx, cls, inst, parent, tag_name, subelts, add_type=False
+ )
def schema_validation_error_to_parent(self, ctx, cls, inst, parent, ns, **_):
subelts = [
@@ -148,10 +155,11 @@ def fault_from_element(self, ctx, cls, element):
role = element.find("soap:Role", namespaces=nsmap)
node = element.find("soap:Node", namespaces=nsmap)
detail = element.find("soap:Detail", namespaces=nsmap)
- faultactor = ''
+ faultactor = ""
if role is not None:
faultactor += role.text.strip()
if node is not None:
faultactor += node.text.strip()
- return cls(faultcode=code, faultstring=reason,
- faultactor=faultactor, detail=detail)
+ return cls(
+ faultcode=code, faultstring=reason, faultactor=faultactor, detail=detail
+ )
diff --git a/spyne/protocol/xml.py b/spyne/protocol/xml.py
index ecdd048f9..cb5e00fff 100644
--- a/spyne/protocol/xml.py
+++ b/spyne/protocol/xml.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -29,59 +28,54 @@
to turn it on for a production system.
"""
-
import logging
-logger = logging.getLogger('spyne.protocol.xml')
-logger_invalid = logging.getLogger('spyne.protocol.xml.invalid')
-from inspect import isgenerator
+logger = logging.getLogger("spyne.protocol.xml")
+logger_invalid = logging.getLogger("spyne.protocol.xml.invalid")
+
from collections import defaultdict
+from inspect import isgenerator
-from lxml import etree
-from lxml import html
+from lxml import etree, html
from lxml.builder import E
-from lxml.etree import XMLSyntaxError
-from lxml.etree import XMLParser
-
-from spyne import BODY_STYLE_WRAPPED
-
-from spyne.util import Break, coroutine
-from spyne.util.six import text_type, string_types
-from spyne.util.cdict import cdict
-from spyne.util.etreeconv import etree_to_dict, dict_to_etree,\
- root_dict_to_etree
-from spyne.const.xml import XSI, NS_SOAP11_ENC
-
-from spyne.error import Fault
-from spyne.error import ValidationError
-from spyne.const.ansi_color import LIGHT_GREEN
-from spyne.const.ansi_color import LIGHT_RED
-from spyne.const.ansi_color import END_COLOR
-from spyne.const.xml import NS_SOAP11_ENV
-from spyne.const.xml import PREFMAP, DEFAULT_NS
-
-from spyne.model import Any, ModelBase, Array, Iterable, ComplexModelBase, \
- AnyHtml, AnyXml, AnyDict, Unicode, PushBase, File, ByteArray, XmlData, \
- XmlAttribute
+from lxml.etree import XMLParser, XMLSyntaxError
+
+from spyne.const.ansi_color import END_COLOR, LIGHT_GREEN, LIGHT_RED
+from spyne.const.xml import DEFAULT_NS, NS_SOAP11_ENC, NS_SOAP11_ENV, PREFMAP, XSI
+from spyne.descriptor import BODY_STYLE_WRAPPED
+from spyne.error import Fault, ValidationError
+from spyne.model import (
+ Any,
+ AnyDict,
+ AnyHtml,
+ AnyXml,
+ Array,
+ ByteArray,
+ ComplexModelBase,
+ File,
+ Iterable,
+ ModelBase,
+ PushBase,
+ Unicode,
+ XmlAttribute,
+ XmlData,
+)
from spyne.model.binary import BINARY_ENCODING_BASE64
from spyne.model.enum import EnumBase
-
from spyne.protocol import ProtocolBase
+from spyne.util import Break, coroutine
+from spyne.util.cdict import cdict
+from spyne.util.etreeconv import dict_to_etree, etree_to_dict, root_dict_to_etree
-from spyne.util import six
-
-if six.PY2:
- STR_TYPES = (str, unicode)
-else:
- STR_TYPES = (str, bytes)
+STR_TYPES = (str, bytes)
-NIL_ATTR = {XSI('nil'): 'true'}
-XSI_TYPE = XSI('type')
+NIL_ATTR = {XSI("nil"): "true"}
+XSI_TYPE = XSI("type")
def _append(parent, child_elt):
- if hasattr(parent, 'append'):
+ if hasattr(parent, "append"):
parent.append(child_elt)
else:
parent.write(child_elt)
@@ -96,7 +90,7 @@ def _gen_tagname(ns, name):
class SchemaValidationError(Fault):
"""Raised when the input stream could not be validated by the Xml Schema."""
- CODE = 'Client.SchemaValidationError'
+ CODE = "Client.SchemaValidationError"
def __init__(self, faultstring):
super(SchemaValidationError, self).__init__(self.CODE, faultstring)
@@ -273,39 +267,45 @@ class XmlDocument(SubXmlBase):
SCHEMA_VALIDATION = type("Schema", (object,), {})
- mime_type = 'text/xml'
+ mime_type = "text/xml"
default_binary_encoding = BINARY_ENCODING_BASE64
type = set(ProtocolBase.type)
- type.add('xml')
+ type.add("xml")
soap_env = PREFMAP[NS_SOAP11_ENV]
ns_soap_env = NS_SOAP11_ENV
ns_soap_enc = NS_SOAP11_ENC
- def __init__(self, app=None, validator=None,
- replace_null_with_default=True,
- xml_declaration=True,
- cleanup_namespaces=True, encoding=None, pretty_print=False,
- attribute_defaults=False,
- dtd_validation=False,
- load_dtd=False,
- no_network=True,
- ns_clean=False,
- recover=False,
- remove_blank_text=False,
- remove_pis=True,
- strip_cdata=True,
- resolve_entities=False,
- huge_tree=False,
- compact=True,
- binary_encoding=None,
- parse_xsi_type=True,
- polymorphic=False,
- ):
-
- super(XmlDocument, self).__init__(app, validator,
- binary_encoding=binary_encoding)
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ replace_null_with_default=True,
+ xml_declaration=True,
+ cleanup_namespaces=True,
+ encoding=None,
+ pretty_print=False,
+ attribute_defaults=False,
+ dtd_validation=False,
+ load_dtd=False,
+ no_network=True,
+ ns_clean=False,
+ recover=False,
+ remove_blank_text=False,
+ remove_pis=True,
+ strip_cdata=True,
+ resolve_entities=False,
+ huge_tree=False,
+ compact=True,
+ binary_encoding=None,
+ parse_xsi_type=True,
+ polymorphic=False,
+ ):
+
+ super(XmlDocument, self).__init__(
+ app, validator, binary_encoding=binary_encoding
+ )
self.validation_schema = None
self.xml_declaration = xml_declaration
@@ -313,7 +313,7 @@ def __init__(self, app=None, validator=None,
self.replace_null_with_default = replace_null_with_default
if encoding is None:
- self.encoding = 'UTF-8'
+ self.encoding = "UTF-8"
else:
self.encoding = encoding
@@ -321,35 +321,39 @@ def __init__(self, app=None, validator=None,
self.pretty_print = pretty_print
self.parse_xsi_type = parse_xsi_type
- self.serialization_handlers = cdict({
- Any: self.any_to_parent,
- Fault: self.fault_to_parent,
- EnumBase: self.enum_to_parent,
- AnyXml: self.any_xml_to_parent,
- XmlData: self.xmldata_to_parent,
- AnyDict: self.any_dict_to_parent,
- AnyHtml: self.any_html_to_parent,
- ModelBase: self.modelbase_to_parent,
- ByteArray: self.byte_array_to_parent,
- ComplexModelBase: self.complex_to_parent,
- XmlAttribute: self.xmlattribute_to_parent,
- SchemaValidationError: self.schema_validation_error_to_parent,
- })
-
- self.deserialization_handlers = cdict({
- AnyHtml: self.html_from_element,
- AnyXml: self.xml_from_element,
- Any: self.xml_from_element,
- Array: self.array_from_element,
- Fault: self.fault_from_element,
- AnyDict: self.dict_from_element,
- EnumBase: self.enum_from_element,
- ModelBase: self.base_from_element,
- Unicode: self.unicode_from_element,
- Iterable: self.iterable_from_element,
- ByteArray: self.byte_array_from_element,
- ComplexModelBase: self.complex_from_element,
- })
+ self.serialization_handlers = cdict(
+ {
+ Any: self.any_to_parent,
+ Fault: self.fault_to_parent,
+ EnumBase: self.enum_to_parent,
+ AnyXml: self.any_xml_to_parent,
+ XmlData: self.xmldata_to_parent,
+ AnyDict: self.any_dict_to_parent,
+ AnyHtml: self.any_html_to_parent,
+ ModelBase: self.modelbase_to_parent,
+ ByteArray: self.byte_array_to_parent,
+ ComplexModelBase: self.complex_to_parent,
+ XmlAttribute: self.xmlattribute_to_parent,
+ SchemaValidationError: self.schema_validation_error_to_parent,
+ }
+ )
+
+ self.deserialization_handlers = cdict(
+ {
+ AnyHtml: self.html_from_element,
+ AnyXml: self.xml_from_element,
+ Any: self.xml_from_element,
+ Array: self.array_from_element,
+ Fault: self.fault_from_element,
+ AnyDict: self.dict_from_element,
+ EnumBase: self.enum_from_element,
+ ModelBase: self.base_from_element,
+ Unicode: self.unicode_from_element,
+ Iterable: self.iterable_from_element,
+ ByteArray: self.byte_array_from_element,
+ ComplexModelBase: self.complex_from_element,
+ }
+ )
self.parser_kwargs = dict(
attribute_defaults=attribute_defaults,
@@ -369,12 +373,11 @@ def __init__(self, app=None, validator=None,
)
def set_validator(self, validator):
- if validator in ('lxml', 'schema') or \
- validator is self.SCHEMA_VALIDATION:
+ if validator in ("lxml", "schema") or validator is self.SCHEMA_VALIDATION:
self.validate_document = self.__validate_lxml
self.validator = self.SCHEMA_VALIDATION
- elif validator == 'soft' or validator is self.SOFT_VALIDATION:
+ elif validator == "soft" or validator is self.SOFT_VALIDATION:
self.validator = self.SOFT_VALIDATION
elif validator is None:
@@ -418,34 +421,35 @@ def __validate_lxml(self, payload):
logger.debug("Validated ? %r" % ret)
if ret == False:
- error_text = text_type(self.validation_schema.error_log.last_error)
- raise SchemaValidationError(error_text.encode('ascii',
- 'xmlcharrefreplace'))
+ error_text = str(self.validation_schema.error_log.last_error)
+ raise SchemaValidationError(error_text.encode("ascii", "xmlcharrefreplace"))
def create_in_document(self, ctx, charset=None):
"""Uses the iterable of string fragments in ``ctx.in_string`` to set
``ctx.in_document``."""
- string = b''.join(ctx.in_string)
+ string = b"".join(ctx.in_string)
try:
try:
- ctx.in_document = etree.fromstring(string,
- parser=XMLParser(**self.parser_kwargs))
+ ctx.in_document = etree.fromstring(
+ string, parser=XMLParser(**self.parser_kwargs)
+ )
except ValueError:
- logger.debug('ValueError: Deserializing from unicode strings '
- 'with encoding declaration is not supported by '
- 'lxml.')
- ctx.in_document = etree.fromstring(string.decode(charset),
- self.parser)
+ logger.debug(
+ "ValueError: Deserializing from unicode strings "
+ "with encoding declaration is not supported by "
+ "lxml."
+ )
+ ctx.in_document = etree.fromstring(string.decode(charset), self.parser)
except XMLSyntaxError as e:
logger_invalid.error("%r in string %r", e, string)
- raise Fault('Client.XMLSyntaxError', str(e))
+ raise Fault("Client.XMLSyntaxError", str(e))
def decompose_incoming_envelope(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- ctx.in_header_doc = None # If you need header support, you should use Soap
+ ctx.in_header_doc = None # If you need header support, you should use Soap
ctx.in_body_doc = ctx.in_document
ctx.method_request_string = ctx.in_body_doc.tag
self.validate_body(ctx, message)
@@ -453,9 +457,8 @@ def decompose_incoming_envelope(self, ctx, message):
def from_element(self, ctx, cls, element):
cls_attrs = self.get_cls_attrs(cls)
- if bool(element.get(XSI('nil'))):
- if self.validator is self.SOFT_VALIDATION and not \
- cls_attrs.nillable:
+ if bool(element.get(XSI("nil"))):
+ if self.validator is self.SOFT_VALIDATION and not cls_attrs.nillable:
raise ValidationError(None)
if self.replace_null_with_default:
@@ -469,7 +472,7 @@ def from_element(self, ctx, cls, element):
xsi_type = element.get(XSI_TYPE, None)
if xsi_type is not None:
if ":" in xsi_type:
- prefix, objtype = xsi_type.split(':', 1)
+ prefix, objtype = xsi_type.split(":", 1)
else:
prefix, objtype = None, xsi_type
@@ -478,21 +481,29 @@ def from_element(self, ctx, cls, element):
classkey = "{%s}%s" % (ns, objtype)
else:
- logger.error("xsi:type namespace prefix "
- "'%s' in '%s' not found in %r",
- ns, xsi_type, element.nsmap)
+ logger.error(
+ "xsi:type namespace prefix " "'%s' in '%s' not found in %r",
+ ns,
+ xsi_type,
+ element.nsmap,
+ )
raise ValidationError(xsi_type)
newclass = ctx.app.interface.classes.get(classkey, None)
if newclass is None:
- logger.error("xsi:type '%s' interpreted as class key '%s' "
- "is not recognized", xsi_type, classkey)
+ logger.error(
+ "xsi:type '%s' interpreted as class key '%s' "
+ "is not recognized",
+ xsi_type,
+ classkey,
+ )
raise ValidationError(xsi_type)
cls = newclass
- logger.debug("xsi:type '%s' overrides %r to %r", xsi_type,
- cls, newclass)
+ logger.debug(
+ "xsi:type '%s' overrides %r to %r", xsi_type, cls, newclass
+ )
handler = self.deserialization_handlers[cls]
return handler(ctx, cls, element)
@@ -503,8 +514,7 @@ def to_parent(self, ctx, cls, inst, parent, ns, *args, **kwargs):
subprot = cls_attrs.prot
if subprot is not None and isinstance(subprot, SubXmlBase):
- return subprot.subserialize(ctx, cls, inst, parent, ns,
- *args, **kwargs)
+ return subprot.subserialize(ctx, cls, inst, parent, ns, *args, **kwargs)
handler = self.serialization_handlers[cls]
@@ -512,13 +522,12 @@ def to_parent(self, ctx, cls, inst, parent, ns, *args, **kwargs):
inst = cls_attrs.default
if inst is None:
- return self.null_to_parent(ctx, cls, inst, parent, ns,
- *args, **kwargs)
+ return self.null_to_parent(ctx, cls, inst, parent, ns, *args, **kwargs)
if cls_attrs.exc:
return
- kwargs['add_type'] = add_type
+ kwargs["add_type"] = add_type
return handler(ctx, cls, inst, parent, ns, *args, **kwargs)
def deserialize(self, ctx, message):
@@ -532,12 +541,13 @@ def deserialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_deserialize', ctx)
+ self.event_manager.fire_event("before_deserialize", ctx)
if ctx.descriptor is None:
if ctx.in_error is None:
- raise Fault("Client", "Method %r not found." %
- ctx.method_request_string)
+ raise Fault(
+ "Client", "Method %r not found." % ctx.method_request_string
+ )
else:
raise ctx.in_error
@@ -553,16 +563,19 @@ def deserialize(self, ctx, message):
ctx.in_object = self.from_element(ctx, body_class, ctx.in_body_doc)
if logger.level == logging.DEBUG and message is self.REQUEST:
- line_header = '%sRequest%s' % (LIGHT_GREEN, END_COLOR)
+ line_header = "%sRequest%s" % (LIGHT_GREEN, END_COLOR)
outdoc_str = None
if ctx.out_document is not None:
- outdoc_str = etree.tostring(ctx.out_document,
- xml_declaration=self.xml_declaration, pretty_print=True)
+ outdoc_str = etree.tostring(
+ ctx.out_document,
+ xml_declaration=self.xml_declaration,
+ pretty_print=True,
+ )
logger.debug("%s %s" % (line_header, outdoc_str))
- self.event_manager.fire_event('after_deserialize', ctx)
+ self.event_manager.fire_event("after_deserialize", ctx)
def serialize(self, ctx, message):
"""Uses ``ctx.out_object``, ``ctx.out_header`` or ``ctx.out_error`` to
@@ -574,12 +587,17 @@ def serialize(self, ctx, message):
assert message in (self.REQUEST, self.RESPONSE)
- self.event_manager.fire_event('before_serialize', ctx)
+ self.event_manager.fire_event("before_serialize", ctx)
if ctx.out_error is not None:
- tmp_elt = etree.Element('punk')
- retval = self.to_parent(ctx, ctx.out_error.__class__, ctx.out_error,
- tmp_elt, self.app.interface.get_tns())
+ tmp_elt = etree.Element("punk")
+ retval = self.to_parent(
+ ctx,
+ ctx.out_error.__class__,
+ ctx.out_error,
+ tmp_elt,
+ self.app.interface.get_tns(),
+ )
ctx.out_document = tmp_elt[0]
else:
@@ -592,8 +610,7 @@ def serialize(self, ctx, message):
if ctx.descriptor.body_style == BODY_STYLE_WRAPPED:
result_inst = result_message_class()
- for i, (k, v) in enumerate(
- result_message_class._type_info.items()):
+ for i, (k, v) in enumerate(result_message_class._type_info.items()):
attrs = self.get_cls_attrs(v)
result_inst._safe_set(k, ctx.out_object[i], v, attrs)
@@ -601,19 +618,25 @@ def serialize(self, ctx, message):
result_inst = ctx.out_object
if ctx.out_stream is None:
- tmp_elt = etree.Element('punk')
- retval = self.to_parent(ctx, result_message_class,
- result_inst, tmp_elt, self.app.interface.get_tns())
+ tmp_elt = etree.Element("punk")
+ retval = self.to_parent(
+ ctx,
+ result_message_class,
+ result_inst,
+ tmp_elt,
+ self.app.interface.get_tns(),
+ )
ctx.out_document = tmp_elt[0]
else:
- retval = self.incgen(ctx, result_message_class,
- result_inst, self.app.interface.get_tns())
+ retval = self.incgen(
+ ctx, result_message_class, result_inst, self.app.interface.get_tns()
+ )
if self.cleanup_namespaces and ctx.out_document is not None:
etree.cleanup_namespaces(ctx.out_document)
- self.event_manager.fire_event('after_serialize', ctx)
+ self.event_manager.fire_event("after_serialize", ctx)
return retval
@@ -623,15 +646,26 @@ def create_out_string(self, ctx, charset=None):
if charset is None:
charset = self.encoding
- ctx.out_string = [etree.tostring(ctx.out_document,
- encoding=charset,
- pretty_print=self.pretty_print,
- xml_declaration=self.xml_declaration)]
+ ctx.out_string = [
+ etree.tostring(
+ ctx.out_document,
+ encoding=charset,
+ pretty_print=self.pretty_print,
+ xml_declaration=self.xml_declaration,
+ )
+ ]
if logger.level == logging.DEBUG:
- logger.debug('%sResponse%s %s' % (LIGHT_RED, END_COLOR,
- etree.tostring(ctx.out_document,
- pretty_print=True, encoding='UTF-8')))
+ logger.debug(
+ "%sResponse%s %s"
+ % (
+ LIGHT_RED,
+ END_COLOR,
+ etree.tostring(
+ ctx.out_document, pretty_print=True, encoding="UTF-8"
+ ),
+ )
+ )
@coroutine
def incgen(self, ctx, cls, inst, ns, name=None):
@@ -642,7 +676,7 @@ def incgen(self, ctx, cls, inst, ns, name=None):
if isgenerator(ret):
try:
while True:
- y = (yield) # may throw Break
+ y = yield # may throw Break
ret.send(y)
except Break:
@@ -651,7 +685,7 @@ def incgen(self, ctx, cls, inst, ns, name=None):
except StopIteration:
pass
- if hasattr(ctx.out_stream, 'finish'):
+ if hasattr(ctx.out_stream, "finish"):
ctx.out_stream.finish()
def _gen_tag(self, cls, ns, name, add_type=False, **_):
@@ -664,20 +698,17 @@ def _gen_tag(self, cls, ns, name, add_type=False, **_):
return retval
- def byte_array_to_parent(self, ctx, cls, inst, parent, ns, name='retval',
- **kwargs):
+ def byte_array_to_parent(self, ctx, cls, inst, parent, ns, name="retval", **kwargs):
elt = self._gen_tag(cls, ns, name, **kwargs)
elt.text = self.to_unicode(cls, inst, self.binary_encoding)
_append(parent, elt)
- def modelbase_to_parent(self, ctx, cls, inst, parent, ns, name='retval',
- **kwargs):
+ def modelbase_to_parent(self, ctx, cls, inst, parent, ns, name="retval", **kwargs):
elt = self._gen_tag(cls, ns, name, **kwargs)
elt.text = self.to_unicode(cls, inst)
_append(parent, elt)
- def null_to_parent(self, ctx, cls, inst, parent, ns, name='retval',
- **kwargs):
+ def null_to_parent(self, ctx, cls, inst, parent, ns, name="retval", **kwargs):
if issubclass(cls, XmlAttribute):
return
@@ -692,8 +723,7 @@ def null_to_parent(self, ctx, cls, inst, parent, ns, name='retval',
def null_from_element(self, ctx, cls, element):
return None
- def xmldata_to_parent(self, ctx, cls, inst, parent, ns, name,
- add_type=False, **_):
+ def xmldata_to_parent(self, ctx, cls, inst, parent, ns, name, add_type=False, **_):
cls_attrs = self.get_cls_attrs(cls)
ns = cls._ns
@@ -717,14 +747,12 @@ def xmlattribute_to_parent(self, ctx, cls, inst, parent, ns, name, **_):
if inst is not None:
if issubclass(cls.type, (ByteArray, File)):
- parent.set(name, self.to_unicode(cls.type, inst,
- self.binary_encoding))
+ parent.set(name, self.to_unicode(cls.type, inst, self.binary_encoding))
else:
parent.set(name, self.to_unicode(cls.type, inst))
@coroutine
- def gen_members_parent(self, ctx, cls, inst, parent, tag_name, subelts,
- add_type):
+ def gen_members_parent(self, ctx, cls, inst, parent, tag_name, subelts, add_type):
attrib = {}
if add_type:
tnn = cls.get_type_name_ns(self.app.interface)
@@ -744,7 +772,7 @@ def gen_members_parent(self, ctx, cls, inst, parent, tag_name, subelts,
if isgenerator(ret):
try:
while True:
- y = (yield) # may throw Break
+ y = yield # may throw Break
ret.send(y)
except Break:
@@ -761,7 +789,7 @@ def gen_members_parent(self, ctx, cls, inst, parent, tag_name, subelts,
if isgenerator(ret):
try:
while True:
- y = (yield)
+ y = yield
ret.send(y)
except Break:
@@ -773,14 +801,14 @@ def gen_members_parent(self, ctx, cls, inst, parent, tag_name, subelts,
@coroutine
def _get_members_etree(self, ctx, cls, inst, parent):
try:
- parent_cls = getattr(cls, '__extends__', None)
+ parent_cls = getattr(cls, "__extends__", None)
if not (parent_cls is None):
ret = self._get_members_etree(ctx, parent_cls, inst, parent)
if ret is not None:
try:
while True:
- sv2 = (yield) # may throw Break
+ sv2 = yield # may throw Break
ret.send(sv2)
except Break:
@@ -814,13 +842,12 @@ def _get_members_etree(self, ctx, cls, inst, parent):
if subvalue is not None and mo > 1:
if isinstance(subvalue, PushBase):
while True:
- sv = (yield)
- ret = self.to_parent(ctx, v, sv, parent, sub_ns,
- sub_name)
+ sv = yield
+ ret = self.to_parent(ctx, v, sv, parent, sub_ns, sub_name)
if ret is not None:
try:
while True:
- sv2 = (yield) # may throw Break
+ sv2 = yield # may throw Break
ret.send(sv2)
except Break:
@@ -831,13 +858,12 @@ def _get_members_etree(self, ctx, cls, inst, parent):
else:
for sv in subvalue:
- ret = self.to_parent(ctx, v, sv, parent, sub_ns,
- sub_name)
+ ret = self.to_parent(ctx, v, sv, parent, sub_ns, sub_name)
if ret is not None:
try:
while True:
- sv2 = (yield) # may throw Break
+ sv2 = yield # may throw Break
ret.send(sv2)
except Break:
@@ -849,12 +875,11 @@ def _get_members_etree(self, ctx, cls, inst, parent):
# Don't include empty values for
# non-nillable optional attributes.
elif subvalue is not None or v.Attributes.min_occurs > 0:
- ret = self.to_parent(ctx, v, subvalue, parent, sub_ns,
- sub_name)
+ ret = self.to_parent(ctx, v, subvalue, parent, sub_ns, sub_name)
if ret is not None:
try:
while True:
- sv2 = (yield)
+ sv2 = yield
ret.send(sv2)
except Break as b:
try:
@@ -865,8 +890,9 @@ def _get_members_etree(self, ctx, cls, inst, parent):
except Break:
pass
- def complex_to_parent(self, ctx, cls, inst, parent, ns, name=None,
- add_type=False, **_):
+ def complex_to_parent(
+ self, ctx, cls, inst, parent, ns, name=None, add_type=False, **_
+ ):
cls_attrs = self.get_cls_attrs(cls)
sub_name = cls_attrs.sub_name
@@ -883,54 +909,54 @@ def complex_to_parent(self, ctx, cls, inst, parent, ns, name=None,
inst = cls.get_serialization_instance(inst)
- return self.gen_members_parent(ctx, cls, inst, parent, tag_name, [],
- add_type)
+ return self.gen_members_parent(ctx, cls, inst, parent, tag_name, [], add_type)
def _fault_to_parent_impl(self, ctx, cls, inst, parent, ns, subelts, **_):
tag_name = "{%s}Fault" % self.ns_soap_env
# Accepting raw lxml objects as detail is DEPRECATED. It's also not
# documented. It's kept for backwards-compatibility purposes.
- if isinstance(inst.detail, string_types + (etree._Element,)):
- _append(subelts, E('detail', inst.detail))
+ if isinstance(inst.detail, (str, etree._Element)):
+ _append(subelts, E("detail", inst.detail))
elif isinstance(inst.detail, dict):
if len(inst.detail) > 0:
- _append(subelts, root_dict_to_etree({'detail':inst.detail}))
+ _append(subelts, root_dict_to_etree({"detail": inst.detail}))
elif inst.detail is None:
pass
else:
- raise TypeError('Fault detail Must be dict, got', type(inst.detail))
+ raise TypeError("Fault detail Must be dict, got", type(inst.detail))
# add other nonstandard fault subelements with get_members_etree
- return self.gen_members_parent(ctx, cls, inst, parent, tag_name,
- subelts, add_type=False)
+ return self.gen_members_parent(
+ ctx, cls, inst, parent, tag_name, subelts, add_type=False
+ )
def fault_to_parent(self, ctx, cls, inst, parent, ns, *args, **kwargs):
subelts = [
- E("faultcode", '%s:%s' % (self.soap_env, inst.faultcode)),
+ E("faultcode", "%s:%s" % (self.soap_env, inst.faultcode)),
E("faultstring", inst.faultstring),
E("faultactor", inst.faultactor),
]
return self._fault_to_parent_impl(ctx, cls, inst, parent, ns, subelts)
- def schema_validation_error_to_parent(self, ctx, cls, inst, parent, ns,**_):
+ def schema_validation_error_to_parent(self, ctx, cls, inst, parent, ns, **_):
subelts = [
- E("faultcode", '%s:%s' % (self.soap_env, inst.faultcode)),
+ E("faultcode", "%s:%s" % (self.soap_env, inst.faultcode)),
# HACK: Does anyone know a better way of injecting raw xml entities?
E("faultstring", html.fromstring(inst.faultstring).text),
E("faultactor", inst.faultactor),
]
if inst.detail != None:
- _append(subelts, E('detail', inst.detail))
+ _append(subelts, E("detail", inst.detail))
# add other nonstandard fault subelements with get_members_etree
return self._fault_to_parent_impl(ctx, cls, inst, parent, ns, subelts)
- def enum_to_parent(self, ctx, cls, inst, parent, ns, name='retval', **kwargs):
+ def enum_to_parent(self, ctx, cls, inst, parent, ns, name="retval", **kwargs):
self.modelbase_to_parent(ctx, cls, str(inst), parent, ns, name, **kwargs)
def any_xml_to_parent(self, ctx, cls, inst, parent, ns, name, **_):
@@ -943,7 +969,7 @@ def any_to_parent(self, ctx, cls, inst, parent, ns, name, **_):
_append(parent, E(_gen_tagname(ns, name), inst))
def any_html_to_parent(self, ctx, cls, inst, parent, ns, name, **_):
- if isinstance(inst, string_types) and len(inst) > 0:
+ if isinstance(inst, str) and len(inst) > 0:
inst = html.fromstring(inst)
_append(parent, E(_gen_tagname(ns, name), inst))
@@ -967,8 +993,9 @@ def complex_from_element(self, ctx, cls, elt):
for xtba_key, xtba_type in cls_attrs._xml_tag_body_as:
xtba_attrs = self.get_cls_attrs(xtba_type.type)
if issubclass(xtba_type.type, (ByteArray, File)):
- value = self.from_unicode(xtba_type.type, elt.text,
- self.binary_encoding)
+ value = self.from_unicode(
+ xtba_type.type, elt.text, self.binary_encoding
+ )
else:
value = self.from_unicode(xtba_type.type, elt.text)
@@ -979,7 +1006,7 @@ def complex_from_element(self, ctx, cls, elt):
if isinstance(c, etree._Comment):
continue
- key = c.tag.split('}', 1)[-1]
+ key = c.tag.split("}", 1)[-1]
frequencies[key] += 1
member = flat_type_info.get(key, None)
@@ -1037,8 +1064,7 @@ def complex_from_element(self, ctx, cls, elt):
continue
if issubclass(member.type, (ByteArray, File)):
- value = self.from_unicode(member.type, value_str,
- self.binary_encoding)
+ value = self.from_unicode(member.type, value_str, self.binary_encoding)
else:
value = self.from_unicode(member.type, value_str)
@@ -1050,13 +1076,15 @@ def complex_from_element(self, ctx, cls, elt):
val = frequencies.get(key, 0)
attr = self.get_cls_attrs(c)
if val < attr.min_occurs or val > attr.max_occurs:
- raise Fault('Client.ValidationError', '%r member does not '
- 'respect frequency constraints.' % key)
+ raise Fault(
+ "Client.ValidationError",
+ "%r member does not " "respect frequency constraints." % key,
+ )
return inst
def array_from_element(self, ctx, cls, element):
- retval = [ ]
+ retval = []
(serializer,) = cls._type_info.values()
for child in element.getchildren():
@@ -1072,20 +1100,20 @@ def iterable_from_element(self, ctx, cls, element):
def enum_from_element(self, ctx, cls, element):
if self.validator is self.SOFT_VALIDATION and not (
- cls.validate_string(cls, element.text)):
+ cls.validate_string(cls, element.text)
+ ):
raise ValidationError(element.text)
return getattr(cls, element.text)
def fault_from_element(self, ctx, cls, element):
- code = element.find('faultcode').text
- string = element.find('faultstring').text
- factor = element.find('faultactor')
+ code = element.find("faultcode").text
+ string = element.find("faultstring").text
+ factor = element.find("faultactor")
if factor is not None:
factor = factor.text
- detail = element.find('detail')
+ detail = element.find("detail")
- return cls(faultcode=code, faultstring=string, faultactor=factor,
- detail=detail)
+ return cls(faultcode=code, faultstring=string, faultactor=factor, detail=detail)
def xml_from_element(self, ctx, cls, element):
children = element.getchildren()
@@ -1118,43 +1146,49 @@ def dict_from_element(self, ctx, cls, element):
def unicode_from_element(self, ctx, cls, element):
if self.validator is self.SOFT_VALIDATION and not (
- cls.validate_string(cls, element.text)):
+ cls.validate_string(cls, element.text)
+ ):
raise ValidationError(element.text)
s = element.text
if s is None:
- s = ''
+ s = ""
retval = self.from_unicode(cls, s)
if self.validator is self.SOFT_VALIDATION and not (
- cls.validate_native(cls, retval)):
+ cls.validate_native(cls, retval)
+ ):
raise ValidationError(retval)
return retval
def base_from_element(self, ctx, cls, element):
if self.validator is self.SOFT_VALIDATION and not (
- cls.validate_string(cls, element.text)):
+ cls.validate_string(cls, element.text)
+ ):
raise ValidationError(element.text)
retval = self.from_unicode(cls, element.text)
if self.validator is self.SOFT_VALIDATION and not (
- cls.validate_native(cls, retval)):
+ cls.validate_native(cls, retval)
+ ):
raise ValidationError(retval)
return retval
def byte_array_from_element(self, ctx, cls, element):
if self.validator is self.SOFT_VALIDATION and not (
- cls.validate_string(cls, element.text)):
+ cls.validate_string(cls, element.text)
+ ):
raise ValidationError(element.text)
retval = self.from_unicode(cls, element.text, self.binary_encoding)
if self.validator is self.SOFT_VALIDATION and not (
- cls.validate_native(cls, retval)):
+ cls.validate_native(cls, retval)
+ ):
raise ValidationError(retval)
return retval
diff --git a/spyne/protocol/yaml.py b/spyne/protocol/yaml.py
index 1a9a46a1a..c7f4337e0 100644
--- a/spyne/protocol/yaml.py
+++ b/spyne/protocol/yaml.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -26,34 +25,28 @@
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
-from spyne import ValidationError
-from spyne.util import six
+import yaml
+from yaml.parser import ParserError
+
from spyne.model.binary import BINARY_ENCODING_BASE64
-from spyne.model.primitive import Boolean
-from spyne.model.primitive import Integer
-from spyne.model.primitive import Double
-from spyne.model.fault import Fault
+from spyne.model.fault import Fault, ValidationError
+from spyne.model.primitive import Boolean, Double, Integer
from spyne.protocol.dictdoc import HierDictDocument
-import yaml
-
-from yaml.parser import ParserError
try:
- from yaml import CLoader as Loader
from yaml import CDumper as Dumper
- from yaml import CSafeLoader as SafeLoader
+ from yaml import CLoader as Loader
from yaml import CSafeDumper as SafeDumper
+ from yaml import CSafeLoader as SafeLoader
except ImportError:
- from yaml import Loader
- from yaml import Dumper
- from yaml import SafeLoader
- from yaml import SafeDumper
+ from yaml import Dumper, Loader, SafeDumper, SafeLoader
-NON_NUMBER_TYPES = tuple({list, dict, six.text_type, six.binary_type})
+NON_NUMBER_TYPES = tuple({list, dict, str, bytes})
class YamlDocument(HierDictDocument):
@@ -72,10 +65,10 @@ class YamlDocument(HierDictDocument):
``indent=4`` by default.
"""
- mime_type = 'text/yaml'
+ mime_type = "text/yaml"
type = set(HierDictDocument.type)
- type.add('yaml')
+ type.add("yaml")
text_based = True
@@ -84,21 +77,34 @@ class YamlDocument(HierDictDocument):
# for test classes
_decimal_as_string = True
- def __init__(self, app=None, validator=None, mime_type=None,
- ignore_uncap=False,
- # DictDocument specific
- ignore_wrappers=True,
- complex_as=dict,
- ordered=False,
- polymorphic=False,
- # YamlDocument specific
- safe=True,
- encoding='UTF-8',
- allow_unicode=True,
- **kwargs):
-
- super(YamlDocument, self).__init__(app, validator, mime_type,
- ignore_uncap, ignore_wrappers, complex_as, ordered, polymorphic)
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ mime_type=None,
+ ignore_uncap=False,
+ # DictDocument specific
+ ignore_wrappers=True,
+ complex_as=dict,
+ ordered=False,
+ polymorphic=False,
+ # YamlDocument specific
+ safe=True,
+ encoding="UTF-8",
+ allow_unicode=True,
+ **kwargs,
+ ):
+
+ super(YamlDocument, self).__init__(
+ app,
+ validator,
+ mime_type,
+ ignore_uncap,
+ ignore_wrappers,
+ complex_as,
+ ordered,
+ polymorphic,
+ )
self._from_unicode_handlers[Double] = self._ret_number
self._from_unicode_handlers[Boolean] = self._ret_bool
@@ -112,25 +118,24 @@ def __init__(self, app=None, validator=None, mime_type=None,
dumper = Dumper
if safe:
loader = SafeLoader
- dumper = SafeDumper
+ dumper = SafeDumper
self.in_kwargs = dict(kwargs)
self.out_kwargs = dict(kwargs)
- self.in_kwargs['Loader'] = loader
- self.out_kwargs['Dumper'] = dumper
+ self.in_kwargs["Loader"] = loader
+ self.out_kwargs["Dumper"] = dumper
- loader.add_constructor('tag:yaml.org,2002:python/unicode',
- _unicode_loader)
+ loader.add_constructor("tag:yaml.org,2002:python/unicode", _unicode_loader)
- self.out_kwargs['encoding'] = encoding
- self.out_kwargs['allow_unicode'] = allow_unicode
+ self.out_kwargs["encoding"] = encoding
+ self.out_kwargs["allow_unicode"] = allow_unicode
- if not 'indent' in self.out_kwargs:
- self.out_kwargs['indent'] = 4
+ if not "indent" in self.out_kwargs:
+ self.out_kwargs["indent"] = 4
- if not 'default_flow_style' in self.out_kwargs:
- self.out_kwargs['default_flow_style'] = False
+ if not "default_flow_style" in self.out_kwargs:
+ self.out_kwargs["default_flow_style"] = False
def _ret(self, _, value):
return value
@@ -151,28 +156,23 @@ def create_in_document(self, ctx, in_string_encoding=None):
"""Sets ``ctx.in_document`` using ``ctx.in_string``."""
if in_string_encoding is None:
- in_string_encoding = 'UTF-8'
+ in_string_encoding = "UTF-8"
try:
try:
- s = b''.join(ctx.in_string).decode(in_string_encoding)
+ s = b"".join(ctx.in_string).decode(in_string_encoding)
except TypeError:
- s = ''.join(ctx.in_string)
+ s = "".join(ctx.in_string)
ctx.in_document = yaml.load(s, **self.in_kwargs)
except ParserError as e:
- raise Fault('Client.YamlDecodeError', repr(e))
+ raise Fault("Client.YamlDecodeError", repr(e))
- def create_out_string(self, ctx, out_string_encoding='utf8'):
+ def create_out_string(self, ctx, out_string_encoding="utf8"):
"""Sets ``ctx.out_string`` using ``ctx.out_document``."""
- ctx.out_string = (yaml.dump(o, **self.out_kwargs)
- for o in ctx.out_document)
- if six.PY2 and out_string_encoding is not None:
- ctx.out_string = (
- yaml.dump(o, **self.out_kwargs).encode(out_string_encoding)
- for o in ctx.out_document)
+ ctx.out_string = (yaml.dump(o, **self.out_kwargs) for o in ctx.out_document)
def _unicode_loader(loader, node):
diff --git a/spyne/server/__init__.py b/spyne/server/__init__.py
index 5ab65844f..ef5bfd84a 100644
--- a/spyne/server/__init__.py
+++ b/spyne/server/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
diff --git a/spyne/server/_base.py b/spyne/server/_base.py
index d73468d41..f195c1795 100644
--- a/spyne/server/_base.py
+++ b/spyne/server/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,13 +17,15 @@
#
import logging
+
logger = logging.getLogger(__name__)
from inspect import isgenerator
-from spyne import EventManager, Ignored
from spyne.auxproc import process_contexts
+from spyne.evmgr import EventManager
from spyne.model import Fault, PushBase
+from spyne.model._base import Ignored
from spyne.protocol import ProtocolBase
from spyne.util import Break, coroutine
@@ -70,8 +71,7 @@ def generate_contexts(self, ctx, in_string_charset=None):
# sets ctx.in_body_doc, ctx.in_header_doc and
# ctx.method_request_string
- self.app.in_protocol.decompose_incoming_envelope(ctx,
- ProtocolBase.REQUEST)
+ self.app.in_protocol.decompose_incoming_envelope(ctx, ProtocolBase.REQUEST)
# returns a list of contexts. multiple contexts can be returned
# when the requested method also has bound auxiliary methods.
@@ -84,7 +84,7 @@ def generate_contexts(self, ctx, in_string_charset=None):
retval = (ctx,)
- ctx.fire_event('method_exception_object')
+ ctx.fire_event("method_exception_object")
return retval
@@ -94,8 +94,7 @@ def get_in_object(self, ctx):
try:
# sets ctx.in_object and ctx.in_header
- self.app.in_protocol.deserialize(ctx,
- message=self.app.in_protocol.REQUEST)
+ self.app.in_protocol.deserialize(ctx, message=self.app.in_protocol.REQUEST)
except Fault as e:
logger.exception(e)
@@ -105,7 +104,7 @@ def get_in_object(self, ctx):
ctx.in_error = e
ctx.out_error = e
- ctx.fire_event('method_exception_object')
+ ctx.fire_event("method_exception_object")
def get_out_object(self, ctx):
"""Calls the matched user function by passing it the ``ctx.in_object``
@@ -117,16 +116,18 @@ def get_out_object(self, ctx):
else:
raise ctx.in_error
- if isinstance(ctx.out_object, (list, tuple)) \
- and len(ctx.out_object) > 0 \
- and isinstance(ctx.out_object[0], Ignored):
+ if (
+ isinstance(ctx.out_object, (list, tuple))
+ and len(ctx.out_object) > 0
+ and isinstance(ctx.out_object[0], Ignored)
+ ):
ctx.out_object = (None,)
elif isinstance(ctx.out_object, Ignored):
ctx.out_object = ()
def convert_pull_to_push(self, ctx, gen):
- oobj, = ctx.out_object
+ (oobj,) = ctx.out_object
if oobj is None:
gen.throw(Break())
@@ -155,8 +156,11 @@ def get_out_string_pull(self, ctx):
if ctx.out_document is None:
ret = ctx.out_protocol.serialize(ctx, message=ProtocolBase.RESPONSE)
- if isgenerator(ret) and ctx.out_object is not None and \
- len(ctx.out_object) == 1:
+ if (
+ isgenerator(ret)
+ and ctx.out_object is not None
+ and len(ctx.out_object) == 1
+ ):
if len(ctx.pusher_stack) > 0:
# we suspend request processing here because there now
# seems to be a PushBase waiting for input.
@@ -166,19 +170,19 @@ def get_out_string_pull(self, ctx):
def finalize_context(self, ctx):
if ctx.out_error is None:
- ctx.fire_event('method_return_document')
+ ctx.fire_event("method_return_document")
else:
- ctx.fire_event('method_exception_document')
+ ctx.fire_event("method_exception_document")
ctx.out_protocol.create_out_string(ctx)
if ctx.out_error is None:
- ctx.fire_event('method_return_string')
+ ctx.fire_event("method_return_string")
else:
- ctx.fire_event('method_exception_string')
+ ctx.fire_event("method_exception_string")
if ctx.out_string is None:
- ctx.out_string = (b'',)
+ ctx.out_string = (b"",)
# for backwards compatibility
get_out_string = get_out_string_pull
@@ -191,7 +195,7 @@ def get_out_string_push(self, ctx):
if isgenerator(ret):
try:
while True:
- y = (yield)
+ y = yield
ret.send(y)
except Break:
@@ -217,7 +221,7 @@ def init_interim_push(self, ret, p_ctx, gen):
# the machinery in ServerBase can initialize them using this function.
# fire events
- p_ctx.fire_event('method_return_push')
+ p_ctx.fire_event("method_return_push")
def _cb_push_finish():
process_contexts(self, (), p_ctx)
@@ -239,25 +243,25 @@ def init_root_push(self, ret, p_ctx, others):
assert isinstance(ret, PushBase)
if ret in p_ctx.pusher_stack:
- logger.warning('PushBase reinit avoided.')
+ logger.warning("PushBase reinit avoided.")
return
p_ctx.pusher_stack.append(ret)
# fire events
- p_ctx.fire_event('method_return_push')
+ p_ctx.fire_event("method_return_push")
# start push serialization
gen = self.get_out_string_push(p_ctx)
- assert isgenerator(gen), "It looks like this protocol is not " \
- "async-compliant yet."
+ assert isgenerator(gen), (
+ "It looks like this protocol is not " "async-compliant yet."
+ )
def _cb_push_finish():
process_contexts(self, others, p_ctx)
- retval = self.pusher_init(p_ctx, gen, _cb_push_finish, ret,
- interim=False)
+ retval = self.pusher_init(p_ctx, gen, _cb_push_finish, ret, interim=False)
self.pusher_try_close(p_ctx, ret, retval)
diff --git a/spyne/server/django.py b/spyne/server/django.py
index e6d07cbc7..855a95f6d 100644
--- a/spyne/server/django.py
+++ b/spyne/server/django.py
@@ -25,28 +25,30 @@
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
from functools import update_wrapper
+from django.http import Http404, HttpResponse, HttpResponseNotAllowed
+from django.views.decorators.csrf import csrf_exempt
+
from spyne import Address
-from spyne.application import get_fault_string_from_exception, Application
+from spyne.application import Application, get_fault_string_from_exception
from spyne.auxproc import process_contexts
from spyne.model.fault import Fault
-from spyne.protocol.soap import Soap11
from spyne.protocol.http import HttpRpc
+from spyne.protocol.soap import Soap11
from spyne.server.http import HttpBase, HttpMethodContext, HttpTransportContext
from spyne.server.wsgi import WsgiApplication
from spyne.util import _bytes_join
from spyne.util.address import address_parser
-from django.http import HttpResponse, HttpResponseNotAllowed, Http404
-from django.views.decorators.csrf import csrf_exempt
-
try:
from django.http import StreamingHttpResponse
except ImportError as _import_error:
_local_import_error = _import_error
+
def StreamingHttpResponse(*args, **kwargs):
raise _local_import_error
@@ -64,7 +66,7 @@ def __call__(self, request):
def start_response(status, headers):
# Status is one of spyne.const.http
- status, reason = status.split(' ', 1)
+ status, reason = status.split(" ", 1)
retval.status_code = int(status)
for header, value in headers:
@@ -82,8 +84,8 @@ def start_response(status, headers):
# would hang waiting for extra request data. Use DjangoServer instead
# of monkeypatching wsgi.inpu.
- #environ['wsgi.input'] = request
- #environ['wsgi.multithread'] = False
+ # environ['wsgi.input'] = request
+ # environ['wsgi.multithread'] = False
response = WsgiApplication.__call__(self, environ, start_response)
self.set_response(retval, response)
@@ -114,7 +116,7 @@ def get_request_method(self):
return self.req.method
def get_request_content_type(self):
- return self.req.META['CONTENT_TYPE']
+ return self.req.META["CONTENT_TYPE"]
def get_path_and_qs(self):
return self.req.get_full_path()
@@ -123,8 +125,9 @@ def get_cookie(self, key):
return self.req.COOKIES[key]
def get_peer(self):
- addr, port = address_parser.get_ip(self.req.META),\
- address_parser.get_port(self.req.META)
+ addr, port = address_parser.get_ip(self.req.META), address_parser.get_port(
+ self.req.META
+ )
if address_parser.is_valid_ipv4(addr, port):
return Address(type=Address.TCP4, host=addr, port=port)
@@ -175,12 +178,12 @@ def handle_rpc(self, request, *args, **kwargs):
except Exception as e:
logger.exception(e)
- p_ctx.out_error = Fault('Server',
- get_fault_string_from_exception(e))
+ p_ctx.out_error = Fault("Server", get_fault_string_from_exception(e))
return self.handle_error(p_ctx, others, p_ctx.out_error)
- have_protocol_headers = (isinstance(p_ctx.out_protocol, HttpRpc) and
- p_ctx.out_header_doc is not None)
+ have_protocol_headers = (
+ isinstance(p_ctx.out_protocol, HttpRpc) and p_ctx.out_header_doc is not None
+ )
if have_protocol_headers:
p_ctx.transport.resp_headers.update(p_ctx.out_header_doc)
@@ -191,17 +194,16 @@ def handle_rpc(self, request, *args, **kwargs):
if self.chunked:
response = StreamingHttpResponse(p_ctx.out_string)
else:
- response = HttpResponse(b''.join(p_ctx.out_string))
+ response = HttpResponse(b"".join(p_ctx.out_string))
return self.response(response, p_ctx, others)
def handle_wsdl(self, request, *args, **kwargs):
"""Return services WSDL."""
- ctx = HttpMethodContext(self, request,
- 'text/xml; charset=utf-8')
+ ctx = HttpMethodContext(self, request, "text/xml; charset=utf-8")
if self.doc.wsdl11 is None:
- raise Http404('WSDL is not available')
+ raise Http404("WSDL is not available")
if self._wsdl is None:
# Interface document building is not thread safe so we don't use
@@ -231,11 +233,12 @@ def handle_error(self, p_ctx, others, error):
"""
if p_ctx.transport.resp_code is None:
- p_ctx.transport.resp_code = \
- p_ctx.out_protocol.fault_to_http_response_code(error)
+ p_ctx.transport.resp_code = p_ctx.out_protocol.fault_to_http_response_code(
+ error
+ )
self.get_out_string(p_ctx)
- resp = HttpResponse(b''.join(p_ctx.out_string))
+ resp = HttpResponse(b"".join(p_ctx.out_string))
return self.response(resp, p_ctx, others, error)
def get_contexts(self, request):
@@ -245,8 +248,9 @@ def get_contexts(self, request):
:returns: generated contexts
"""
- initial_ctx = DjangoHttpMethodContext(self, request,
- self.app.out_protocol.mime_type)
+ initial_ctx = DjangoHttpMethodContext(
+ self, request, self.app.out_protocol.mime_type
+ )
initial_ctx.in_string = [request.body]
return self.generate_contexts(initial_ctx)
@@ -285,16 +289,24 @@ class DjangoView(object):
application = None
server = None
services = ()
- tns = 'spyne.application'
- name = 'Application'
- in_protocol = Soap11(validator='lxml')
+ tns = "spyne.application"
+ name = "Application"
+ in_protocol = Soap11(validator="lxml")
out_protocol = Soap11()
interface = None
chunked = False
cache_wsdl = True
- http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head',
- 'options', 'trace']
+ http_method_names = [
+ "get",
+ "post",
+ "put",
+ "patch",
+ "delete",
+ "head",
+ "options",
+ "trace",
+ ]
def __init__(self, server, **kwargs):
self.server = server
@@ -312,14 +324,16 @@ def as_view(cls, **initkwargs):
# sanitize keyword arguments
for key in initkwargs:
if key in cls.http_method_names:
- raise TypeError("You tried to pass in the %s method name as a "
- "keyword argument to %s(). Don't do that."
- % (key, cls.__name__))
+ raise TypeError(
+ "You tried to pass in the %s method name as a "
+ "keyword argument to %s(). Don't do that." % (key, cls.__name__)
+ )
if not hasattr(cls, key):
- raise TypeError("%s() received an invalid keyword %r. as_view "
- "only accepts arguments that are already "
- "attributes of the class." % (cls.__name__,
- key))
+ raise TypeError(
+ "%s() received an invalid keyword %r. as_view "
+ "only accepts arguments that are already "
+ "attributes of the class." % (cls.__name__, key)
+ )
def get(key):
value = initkwargs.get(key)
@@ -329,20 +343,20 @@ def pop(key):
value = initkwargs.pop(key, None)
return value if value is not None else getattr(cls, key)
- application = get('application') or Application(
- services=get('services'),
- tns=get('tns'),
- name=get('name'),
- in_protocol=get('in_protocol'),
- out_protocol=get('out_protocol'),
+ application = get("application") or Application(
+ services=get("services"),
+ tns=get("tns"),
+ name=get("name"),
+ in_protocol=get("in_protocol"),
+ out_protocol=get("out_protocol"),
+ )
+ server = pop("server") or DjangoServer(
+ application, chunked=get("chunked"), cache_wsdl=get("cache_wsdl")
)
- server = pop('server') or DjangoServer(application,
- chunked=get('chunked'),
- cache_wsdl=get('cache_wsdl'))
def view(request, *args, **kwargs):
self = cls(server=server, **initkwargs)
- if hasattr(self, 'get') and not hasattr(self, 'head'):
+ if hasattr(self, "get") and not hasattr(self, "head"):
self.head = self.get
self.request = request
self.args = args
@@ -363,8 +377,9 @@ def dispatch(self, request, *args, **kwargs):
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
- handler = getattr(self, request.method.lower(),
- self.http_method_not_allowed)
+ handler = getattr(
+ self, request.method.lower(), self.http_method_not_allowed
+ )
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
@@ -376,17 +391,20 @@ def post(self, request, *args, **kwargs):
return self.server.handle_rpc(request, *args, **kwargs)
def http_method_not_allowed(self, request, *args, **kwargs):
- logger.warning('Method Not Allowed (%s): %s', request.method,
- request.path, extra={'status_code': 405, 'request':
- self.request})
+ logger.warning(
+ "Method Not Allowed (%s): %s",
+ request.method,
+ request.path,
+ extra={"status_code": 405, "request": self.request},
+ )
return HttpResponseNotAllowed(self._allowed_methods())
def options(self, request, *args, **kwargs):
"""Handle responding to requests for the OPTIONS HTTP verb."""
response = HttpResponse()
- response['Allow'] = ', '.join(self._allowed_methods())
- response['Content-Length'] = '0'
+ response["Allow"] = ", ".join(self._allowed_methods())
+ response["Content-Length"] = "0"
return response
def _allowed_methods(self):
diff --git a/spyne/server/http.py b/spyne/server/http.py
index e80dbde76..eecd01e0e 100644
--- a/spyne/server/http.py
+++ b/spyne/server/http.py
@@ -18,22 +18,21 @@
#
from collections import defaultdict
-
from email import utils
-from email.utils import encode_rfc2231
from email.message import tspecials
+from email.utils import encode_rfc2231
-from spyne import TransportContext, MethodDescriptor, MethodContext, Redirect
-from spyne.server import ServerBase
+from spyne.const.http import HTTP_301, HTTP_302, HTTP_303, HTTP_307, gen_body_redirect
+from spyne.context import MethodContext, TransportContext
+from spyne.descriptor import MethodDescriptor
+from spyne.error import Redirect
from spyne.protocol.http import HttpPattern
-from spyne.const.http import gen_body_redirect, HTTP_301, HTTP_302, HTTP_303, \
- HTTP_307
+from spyne.server import ServerBase
class HttpRedirect(Redirect):
def __init__(self, ctx, location, orig_exc=None, code=HTTP_302):
- super(HttpRedirect, self) \
- .__init__(ctx, location, orig_exc=orig_exc)
+ super(HttpRedirect, self).__init__(ctx, location, orig_exc=orig_exc)
self.ctx = ctx
self.location = location
@@ -48,6 +47,7 @@ def do_redirect(self):
self.ctx.transport.respond(self.code, location=self.location)
+
#
# Plagiarized HttpTransport.add_header() and _formatparam() function from
# Python 2.7 stdlib.
@@ -73,24 +73,24 @@ def _formatparam(param, value=None, quote=True):
# instance. RFC 2231 encoded values are never quoted, per RFC.
if isinstance(value, tuple):
# Encode as per RFC 2231
- param += '*'
+ param += "*"
value = encode_rfc2231(value[2], value[0], value[1])
- return '%s=%s' % (param, value)
+ return "%s=%s" % (param, value)
try:
- value.encode('ascii')
+ value.encode("ascii")
except UnicodeEncodeError:
- param += '*'
- value = encode_rfc2231(value, 'utf-8', '')
- return '%s=%s' % (param, value)
+ param += "*"
+ value = encode_rfc2231(value, "utf-8", "")
+ return "%s=%s" % (param, value)
# BAW: Please check this. I think that if quote is set it should
# force quoting even if not necessary.
if quote or tspecials.search(value):
return '%s="%s"' % (param, utils.quote(value))
- return '%s=%s' % (param, value)
+ return "%s=%s" % (param, value)
class HttpTransportContext(TransportContext):
@@ -98,7 +98,7 @@ class HttpTransportContext(TransportContext):
:class:`HttpMethodContext` class and its subclasses."""
def __init__(self, parent, transport, request, content_type):
- super(HttpTransportContext, self).__init__(parent, transport, 'http')
+ super(HttpTransportContext, self).__init__(parent, transport, "http")
self.req = request
"""HTTP Request. This is transport-specific"""
@@ -119,18 +119,18 @@ def __init__(self, parent, transport, request, content_type):
"""The error when handling WSDL requests."""
def get_mime_type(self):
- return self.resp_headers.get('Content-Type', None)
+ return self.resp_headers.get("Content-Type", None)
def set_mime_type(self, what):
- self.resp_headers['Content-Type'] = what
+ self.resp_headers["Content-Type"] = what
def respond(self, resp_code, **kwargs):
self.resp_code = resp_code
if resp_code in (HTTP_301, HTTP_302, HTTP_303, HTTP_307):
- l = kwargs.pop('location')
- self.resp_headers['Location'] = l
+ l = kwargs.pop("location")
+ self.resp_headers["Location"] = l
self.parent.out_string = [gen_body_redirect(resp_code, l)]
- self.mime_type = 'text/html'
+ self.mime_type = "text/html"
else:
# So that deserialization is skipped.
@@ -163,15 +163,15 @@ def gen_header(_value, **kwargs):
for k, v in kwargs.items():
if v is None:
- parts.append(k.replace('_', '-'))
+ parts.append(k.replace("_", "-"))
else:
- parts.append(_formatparam(k.replace('_', '-'), v))
+ parts.append(_formatparam(k.replace("_", "-"), v))
if _value is not None:
parts.insert(0, _value)
- return '; '.join(parts)
+ return "; ".join(parts)
def add_header(self, _name, _value, **kwargs):
"""Extended header setting.
@@ -221,8 +221,9 @@ class HttpMethodContext(MethodContext):
def __init__(self, transport, req_env, content_type):
super(HttpMethodContext, self).__init__(transport, MethodContext.SERVER)
- self.transport = self.HttpTransportContext(self, transport,
- req_env, content_type)
+ self.transport = self.HttpTransportContext(
+ self, transport, req_env, content_type
+ )
"""Holds the HTTP-specific information"""
def set_out_protocol(self, what):
@@ -237,14 +238,18 @@ def set_out_protocol(self, what):
class HttpBase(ServerBase):
- transport = 'http://schemas.xmlsoap.org/soap/http'
-
- SLASH = '/'
- SLASHPER = '/%s'
-
- def __init__(self, app, chunked=False,
- max_content_length=2 * 1024 * 1024,
- block_length=8 * 1024):
+ transport = "http://schemas.xmlsoap.org/soap/http"
+
+ SLASH = "/"
+ SLASHPER = "/%s"
+
+ def __init__(
+ self,
+ app,
+ chunked=False,
+ max_content_length=2 * 1024 * 1024,
+ block_length=8 * 1024,
+ ):
super(HttpBase, self).__init__(app)
self.chunked = chunked
@@ -263,8 +268,9 @@ def __init__(self, app, chunked=False,
# this makes sure similar addresses with patterns are evaluated after
# addresses with wildcards, which puts the more specific addresses to
# the front.
- self._http_patterns = list(reversed(sorted(self._http_patterns,
- key=lambda x: (x.address, x.host) )))
+ self._http_patterns = list(
+ reversed(sorted(self._http_patterns, key=lambda x: (x.address, x.host)))
+ )
@classmethod
def get_patt_verb(cls, patt):
@@ -278,7 +284,7 @@ def get_patt_host(cls, patt):
def get_patt_address(cls, patt):
return patt.address_re
- def match_pattern(self, ctx, method='', path='', host=''):
+ def match_pattern(self, ctx, method="", path="", host=""):
"""Sets ctx.method_request_string if there's a match. It's O(n) which
means you should keep your number of patterns as low as possible.
@@ -303,7 +309,7 @@ def match_pattern(self, ctx, method='', path='', host=''):
if not (match.span() == (0, len(method))):
continue
- for k,v in match.groupdict().items():
+ for k, v in match.groupdict().items():
params[k].append(v)
if patt.host is not None:
@@ -328,7 +334,7 @@ def match_pattern(self, ctx, method='', path='', host=''):
if not (match.span() == (0, len(path))):
continue
- for k,v in match.groupdict().items():
+ for k, v in match.groupdict().items():
params[k].append(v)
d = patt.endpoint
diff --git a/spyne/server/msgpack.py b/spyne/server/msgpack.py
index 1c0fd4d63..4ed802a03 100644
--- a/spyne/server/msgpack.py
+++ b/spyne/server/msgpack.py
@@ -20,23 +20,25 @@
from __future__ import absolute_import
import logging
-logger = logging.getLogger(__name__)
-import msgpack
+logger = logging.getLogger(__name__)
-from mmap import mmap
from collections import OrderedDict
+from mmap import mmap
+
+import msgpack
-from spyne import MethodContext, TransportContext, Address
+from spyne import Address, MethodContext, TransportContext
from spyne.auxproc import process_contexts
-from spyne.error import ValidationError, InternalError
+from spyne.error import InternalError, ValidationError
from spyne.server import ServerBase
-from spyne.util.six import binary_type
try:
from twisted.internet.defer import Deferred
except ImportError as e:
- def Deferred(*_, **__): raise e
+
+ def Deferred(*_, **__):
+ raise e
MSGPACK_SHELL_OVERHEAD = 10
@@ -45,7 +47,7 @@ def Deferred(*_, **__): raise e
def _process_v1_msg(prot, msg):
header = None
body = msg[1]
- if not isinstance(body, (binary_type, mmap, memoryview)):
+ if not isinstance(body, (bytes, mmap, memoryview)):
raise ValidationError(body, "Body must be a bytestream.")
if len(msg) > 2:
@@ -78,7 +80,7 @@ def get_peer(self):
class MessagePackOobMethodContext(object):
- __slots__ = 'd'
+ __slots__ = "d"
def __init__(self):
if Deferred is not None:
@@ -120,9 +122,7 @@ class MessagePackTransportBase(ServerBase):
def __init__(self, app):
super(MessagePackTransportBase, self).__init__(app)
- self._version_map = {
- self.IN_REQUEST: _process_v1_msg
- }
+ self._version_map = {self.IN_REQUEST: _process_v1_msg}
def produce_contexts(self, msg):
"""Produce contexts based on incoming message.
@@ -136,13 +136,15 @@ def produce_contexts(self, msg):
if not len(msg) >= 2:
logger.debug("Incoming request: %r", msg)
- raise ValidationError(len(msg), "Request must have at least two "
- "elements. It has %r")
+ raise ValidationError(
+ len(msg), "Request must have at least two " "elements. It has %r"
+ )
if not isinstance(msg[0], int):
logger.debug("Incoming request: %r", msg)
- raise ValidationError(msg[0], "Request version must be an integer. "
- "It was %r")
+ raise ValidationError(
+ msg[0], "Request version must be an integer. " "It was %r"
+ )
processor = self._version_map.get(msg[0], None)
if processor is None:
@@ -200,8 +202,9 @@ def handle_transport_error(self, error):
return msgpack.dumps(str(error))
def pack(self, ctx):
- ctx.out_string = msgpack.packb([self.OUT_RESPONSE_NO_ERROR,
- b''.join(ctx.out_string)]),
+ ctx.out_string = (
+ msgpack.packb([self.OUT_RESPONSE_NO_ERROR, b"".join(ctx.out_string)]),
+ )
class MessagePackServerBase(MessagePackTransportBase):
diff --git a/spyne/server/null.py b/spyne/server/null.py
index 27b1f0780..a81dad092 100644
--- a/spyne/server/null.py
+++ b/spyne/server/null.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -26,22 +25,21 @@
from __future__ import absolute_import
import logging
-logger = logging.getLogger(__name__)
-from spyne import MethodContext, BODY_STYLE_BARE, ComplexModelBase, \
- BODY_STYLE_EMPTY, Ignored
+logger = logging.getLogger(__name__)
from spyne.client import Factory
-from spyne.const.ansi_color import LIGHT_RED
-from spyne.const.ansi_color import LIGHT_BLUE
-from spyne.const.ansi_color import END_COLOR
+from spyne.const.ansi_color import END_COLOR, LIGHT_BLUE, LIGHT_RED
+from spyne.context import MethodContext
+from spyne.descriptor import BODY_STYLE_BARE, BODY_STYLE_EMPTY
+from spyne.model._base import Ignored
+from spyne.model.complex import ComplexModelBase
from spyne.server import ServerBase
-
-_big_header = ('=' * 40) + LIGHT_RED
-_big_footer = END_COLOR + ('=' * 40)
-_small_header = ('-' * 20) + LIGHT_BLUE
-_small_footer = END_COLOR + ('-' * 20)
+_big_header = ("=" * 40) + LIGHT_RED
+_big_footer = END_COLOR + ("=" * 40)
+_small_header = ("-" * 20) + LIGHT_BLUE
+_small_footer = END_COLOR + ("-" * 20)
class NullServer(ServerBase):
@@ -57,10 +55,10 @@ class NullServer(ServerBase):
to hide context delimiters in logs.
"""
- transport = 'noconn://null.spyne'
+ transport = "noconn://null.spyne"
MethodContext = MethodContext
- def __init__(self, app, ostr=False, locale='C', appinit=True):
+ def __init__(self, app, ostr=False, locale="C", appinit=True):
self.do_appinit = appinit
super(NullServer, self).__init__(app)
@@ -80,8 +78,7 @@ def get_wsdl(self):
return self.app.get_interface_document(self.url)
def set_options(self, **kwargs):
- self.service.in_header = kwargs.get('soapheaders',
- self.service.in_header)
+ self.service.in_header = kwargs.get("soapheaders", self.service.in_header)
def get_services(self):
return self.app.interface.service_method_map
@@ -95,8 +92,15 @@ def __init__(self, server, app, is_async):
self.is_async = is_async
def __getattr__(self, key):
- return _FunctionCall(self._app, self._server, key, self.in_header,
- self._server.ostr, self._server.locale, self.is_async)
+ return _FunctionCall(
+ self._app,
+ self._server,
+ key,
+ self.in_header,
+ self._server.ostr,
+ self._server.locale,
+ self.is_async,
+ )
def __getitem__(self, key):
return self.__getattr__(key)
@@ -143,8 +147,9 @@ def __call__(self, *args, **kwargs):
ctx.in_object[i] = val
if ctx.descriptor.body_style == BODY_STYLE_BARE:
- ctx.in_object = ctx.descriptor.in_message \
- .get_serialization_instance(ctx.in_object)
+ ctx.in_object = ctx.descriptor.in_message.get_serialization_instance(
+ ctx.in_object
+ )
if cnt == 0:
p_ctx = ctx
@@ -154,15 +159,12 @@ def __call__(self, *args, **kwargs):
# do
# logging.getLogger('spyne.server.null').setLevel(logging.CRITICAL)
# to hide the following
- logger.warning("%s start context %s" % (_small_header,
- _small_footer))
- logger.info("%r.%r" % (ctx.service_class,
- ctx.descriptor.function))
+ logger.warning("%s start context %s" % (_small_header, _small_footer))
+ logger.info("%r.%r" % (ctx.service_class, ctx.descriptor.function))
try:
self.app.process_request(ctx)
finally:
- logger.warning("%s end context %s" % (_small_header,
- _small_footer))
+ logger.warning("%s end context %s" % (_small_header, _small_footer))
if cnt == 0:
if self._async and isinstance(ctx.out_object[0], Deferred):
@@ -204,9 +206,11 @@ def _cb_sync(ctx, cnt, fc):
raise ctx.out_error
else:
- if isinstance(ctx.out_object, (list, tuple)) \
- and len(ctx.out_object) > 0 \
- and isinstance(ctx.out_object[0], Ignored):
+ if (
+ isinstance(ctx.out_object, (list, tuple))
+ and len(ctx.out_object) > 0
+ and isinstance(ctx.out_object[0], Ignored)
+ ):
retval = ctx.out_object[0]
elif ctx.descriptor.is_out_bare():
diff --git a/spyne/server/pyramid.py b/spyne/server/pyramid.py
index 7319da2db..56c2311c4 100644
--- a/spyne/server/pyramid.py
+++ b/spyne/server/pyramid.py
@@ -25,6 +25,7 @@
from __future__ import absolute_import
from pyramid.response import Response
+
from spyne.server.wsgi import WsgiApplication
@@ -35,14 +36,13 @@ def __call__(self, request):
retval = Response()
def start_response(status, headers):
- status, reason = status.split(' ', 1)
+ status, reason = status.split(" ", 1)
retval.status_int = int(status)
for header, value in headers:
retval.headers[header] = value
- response = WsgiApplication.__call__(self, request.environ,
- start_response)
+ response = WsgiApplication.__call__(self, request.environ, start_response)
retval.body = b"".join(response)
return retval
diff --git a/spyne/server/twisted/__init__.py b/spyne/server/twisted/__init__.py
index c22dcaa11..1e4f3bb93 100644
--- a/spyne/server/twisted/__init__.py
+++ b/spyne/server/twisted/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
diff --git a/spyne/server/twisted/_base.py b/spyne/server/twisted/_base.py
index 98a386c88..c60ff5c21 100644
--- a/spyne/server/twisted/_base.py
+++ b/spyne/server/twisted/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -20,7 +19,6 @@
from twisted.internet.defer import Deferred
from twisted.internet.interfaces import IPullProducer
from twisted.web.iweb import UNKNOWN_LENGTH
-
from zope.interface import implementer
@@ -33,7 +31,7 @@ def __init__(self, body, consumer):
# check to see if we can determine the length
try:
- len(body) # iterator?
+ len(body) # iterator?
self.length = sum([len(fragment) for fragment in body])
self.body = iter(body)
@@ -63,17 +61,22 @@ def pauseProducing(self):
def stopProducing(self):
if self.deferred is not None:
- self.deferred.errback(
- Exception("Consumer asked us to stop producing"))
+ self.deferred.errback(Exception("Consumer asked us to stop producing"))
self.deferred = None
from spyne import Address
-_TYPE_MAP = {'TCP': Address.TCP4, 'TCP6': Address.TCP6,
- 'UDP': Address.UDP4, 'UDP6': Address.UDP6}
+
+_TYPE_MAP = {
+ "TCP": Address.TCP4,
+ "TCP6": Address.TCP6,
+ "UDP": Address.UDP4,
+ "UDP6": Address.UDP6,
+}
+
def _address_from_twisted_address(peer):
- return Address(
- type=_TYPE_MAP.get(peer.type, None), host=peer.host, port=peer.port)
+ return Address(type=_TYPE_MAP.get(peer.type, None), host=peer.host, port=peer.port)
+
Address.from_twisted_address = staticmethod(_address_from_twisted_address)
diff --git a/spyne/server/twisted/http.py b/spyne/server/twisted/http.py
index fda93d152..477647fcd 100644
--- a/spyne/server/twisted/http.py
+++ b/spyne/server/twisted/http.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -40,59 +39,46 @@
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
-import re
import cgi
import gzip
+import re
import shutil
import threading
-
-from os import fstat
-from mmap import mmap
-from inspect import isclass
from collections import namedtuple
+from inspect import isclass
+from mmap import mmap
+from os import fstat
from tempfile import TemporaryFile
+from urllib.parse import unquote
+from urllib.request import unquote_to_bytes
-from twisted.web import static
-from twisted.web.server import NOT_DONE_YET, Request
-from twisted.web.resource import Resource, NoResource, ForbiddenResource
-from twisted.web.static import getTypeAndEncoding
-from twisted.python.log import err
-from twisted.python.failure import Failure
from twisted.internet import reactor
-from twisted.internet.task import deferLater
from twisted.internet.defer import Deferred
+from twisted.internet.task import deferLater
from twisted.internet.threads import deferToThread
+from twisted.python.failure import Failure
+from twisted.python.log import err
+from twisted.web import static
+from twisted.web.resource import ForbiddenResource, NoResource, Resource
+from twisted.web.server import NOT_DONE_YET, Request
+from twisted.web.static import getTypeAndEncoding
-from spyne import Redirect, Address
-from spyne.application import logger_server
-from spyne.application import get_fault_string_from_exception
-
-from spyne.util import six
-from spyne.error import InternalError, ValidationError
+from spyne import Address, Redirect
+from spyne.application import get_fault_string_from_exception, logger_server
from spyne.auxproc import process_contexts
-from spyne.const.ansi_color import LIGHT_GREEN
-from spyne.const.ansi_color import END_COLOR
-from spyne.const.http import HTTP_404, HTTP_200
-
-from spyne.model import PushBase, File, ComplexModelBase
+from spyne.const.ansi_color import END_COLOR, LIGHT_GREEN
+from spyne.const.http import HTTP_200, HTTP_404
+from spyne.error import InternalError, ValidationError
+from spyne.model import ComplexModelBase, File, PushBase
from spyne.model.fault import Fault
-
from spyne.protocol.http import HttpRpc
-
-from spyne.server.http import HttpBase
-from spyne.server.http import HttpMethodContext
-from spyne.server.http import HttpTransportContext
-from spyne.server.twisted._base import Producer
+from spyne.server.http import HttpBase, HttpMethodContext, HttpTransportContext
from spyne.server.twisted import log_and_let_go
-
+from spyne.server.twisted._base import Producer
from spyne.util.address import address_parser
-from spyne.util.six import text_type, string_types
-from spyne.util.six.moves.urllib.parse import unquote
-
-if not six.PY2:
- from urllib.request import unquote_to_bytes
def _render_file(file, request):
@@ -103,10 +89,9 @@ def _render_file(file, request):
file.restat(False)
if file.type is None:
- file.type, file.encoding = getTypeAndEncoding(file.basename(),
- file.contentTypes,
- file.contentEncodings,
- file.defaultType)
+ file.type, file.encoding = getTypeAndEncoding(
+ file.basename(), file.contentTypes, file.contentEncodings, file.defaultType
+ )
if not file.exists():
return file.childNotFound.render(request)
@@ -114,7 +99,7 @@ def _render_file(file, request):
if file.isdir():
return file.redirect(request)
- request.setHeader('accept-ranges', 'bytes')
+ request.setHeader("accept-ranges", "bytes")
try:
fileForReading = file.openForReading()
@@ -126,13 +111,13 @@ def _render_file(file, request):
else:
raise
- #if request.setLastModified(file.getmtime()) is CACHED:
+ # if request.setLastModified(file.getmtime()) is CACHED:
# return ''
producer = file.makeProducer(request, fileForReading)
- if request.method == 'HEAD':
- return ''
+ if request.method == "HEAD":
+ return ""
producer.start()
# and make sure the connection doesn't get closed
@@ -165,25 +150,25 @@ def _reconstruct_url(request):
is_secure = request.getHeader(b"x-forwarded-proto")
if is_secure is not None:
- is_secure = is_secure == 'https'
+ is_secure = is_secure == "https"
if server_name is None:
- server_name = request.getRequestHostname().decode('ascii')
+ server_name = request.getRequestHostname().decode("ascii")
if server_port is None:
server_port = request.getHost().port
if is_secure is None:
is_secure = bool(request.isSecure())
if (is_secure, server_port) not in ((True, 443), (False, 80)):
- server_name = '%s:%d' % (server_name, server_port)
+ server_name = "%s:%d" % (server_name, server_port)
if is_secure:
- url_scheme = 'https'
+ url_scheme = "https"
else:
- url_scheme = 'http'
+ url_scheme = "http"
uri = _decode_path(request.uri)
- return ''.join([url_scheme, "://", server_name, uri])
+ return "".join([url_scheme, "://", server_name, uri])
class _Transformer(object):
@@ -192,16 +177,12 @@ def __init__(self, req):
def get(self, key, default):
key = key.lower()
- if six.PY2:
- if key.startswith((b'http_', b'http-')):
+ if isinstance(key, bytes):
+ if key.startswith((b"http_", b"http-")):
key = key[5:]
else:
- if isinstance(key, bytes):
- if key.startswith((b'http_', b'http-')):
- key = key[5:]
- else:
- if key.startswith(('http_', 'http-')):
- key = key[5:]
+ if key.startswith(("http_", "http-")):
+ key = key[5:]
retval = self.req.getHeader(key)
if retval is None:
@@ -211,10 +192,10 @@ def get(self, key, default):
class TwistedHttpTransportContext(HttpTransportContext):
def set_mime_type(self, what):
- if isinstance(what, text_type):
- what = what.encode('ascii', errors='replace')
+ if isinstance(what, str):
+ what = what.encode("ascii", errors="replace")
super(TwistedHttpTransportContext, self).set_mime_type(what)
- self.req.setHeader('Content-Type', what)
+ self.req.setHeader("Content-Type", what)
def get_cookie(self, key):
return self.req.getCookie(key)
@@ -250,17 +231,14 @@ class TwistedHttpMethodContext(HttpMethodContext):
def _decode_path(fragment):
- if six.PY2:
- return unquote(fragment)
-
return unquote_to_bytes(fragment)
class TwistedHttpTransport(HttpBase):
- SLASH = b'/'
- SLASHPER = b'/%s'
+ SLASH = b"/"
+ SLASHPER = b"/%s"
- KEY_ENCODING = 'utf8'
+ KEY_ENCODING = "utf8"
@classmethod
def get_patt_verb(cls, patt):
@@ -274,12 +252,22 @@ def get_patt_host(cls, patt):
def get_patt_address(cls, patt):
return patt.address_b_re
- def __init__(self, app, chunked=False, max_content_length=2 * 1024 * 1024,
- block_length=8 * 1024):
- super(TwistedHttpTransport, self).__init__(app, chunked=chunked,
- max_content_length=max_content_length, block_length=block_length)
+ def __init__(
+ self,
+ app,
+ chunked=False,
+ max_content_length=2 * 1024 * 1024,
+ block_length=8 * 1024,
+ ):
+ super(TwistedHttpTransport, self).__init__(
+ app,
+ chunked=chunked,
+ max_content_length=max_content_length,
+ block_length=block_length,
+ )
self.reactor_thread = None
+
def _cb():
self.reactor_thread = threading.current_thread()
@@ -287,17 +275,25 @@ def _cb():
def pusher_init(self, p_ctx, gen, _cb_push_finish, pusher, interim):
if pusher.orig_thread != self.reactor_thread:
- return deferToThread(super(TwistedHttpTransport, self).pusher_init,
- p_ctx, gen, _cb_push_finish, pusher, interim)
+ return deferToThread(
+ super(TwistedHttpTransport, self).pusher_init,
+ p_ctx,
+ gen,
+ _cb_push_finish,
+ pusher,
+ interim,
+ )
return super(TwistedHttpTransport, self).pusher_init(
- p_ctx, gen, _cb_push_finish, pusher, interim)
+ p_ctx, gen, _cb_push_finish, pusher, interim
+ )
@staticmethod
def set_out_document_push(ctx):
class _ISwearImAGenerator(object):
def send(self, data):
- if not data: return
+ if not data:
+ return
ctx.out_stream.write(data)
ctx.out_document = _ISwearImAGenerator()
@@ -307,13 +303,15 @@ def pusher_try_close(self, ctx, pusher, retval):
# when a *root* pusher has no more data to send. interim pushers don't
# have to close anything.
if isinstance(retval, Deferred):
+
def _eb_push_close(f):
assert isinstance(f, Failure)
logger.error(f.getTraceback())
- subretval = super(TwistedHttpTransport, self) \
- .pusher_try_close(ctx, pusher, retval)
+ subretval = super(TwistedHttpTransport, self).pusher_try_close(
+ ctx, pusher, retval
+ )
if not pusher.interim:
ctx.out_stream.finish()
@@ -328,22 +326,25 @@ def _eb_inner(f):
return f
if not isinstance(r, Deferred):
- retval = super(TwistedHttpTransport, self) \
- .pusher_try_close(ctx, pusher, r)
+ retval = super(TwistedHttpTransport, self).pusher_try_close(
+ ctx, pusher, r
+ )
if not pusher.interim:
ctx.out_stream.finish()
return retval
- return r \
- .addCallback(_cb_push_close) \
- .addErrback(_eb_inner) \
+ return (
+ r.addCallback(_cb_push_close)
+ .addErrback(_eb_inner)
.addErrback(log_and_let_go, logger)
+ )
- return retval \
- .addCallback(_cb_push_close) \
- .addErrback(_eb_push_close) \
+ return (
+ retval.addCallback(_cb_push_close)
+ .addErrback(_eb_push_close)
.addErrback(log_and_let_go, logger)
+ )
super(TwistedHttpTransport, self).pusher_try_close(ctx, pusher, retval)
@@ -358,7 +359,7 @@ def _decode_dict_py2(self, d):
for k, v in d.items():
l = []
for v2 in v:
- if isinstance(v2, string_types):
+ if isinstance(v2, str):
l.append(unquote(v2))
else:
l.append(v2)
@@ -409,30 +410,30 @@ def decompose_incoming_envelope(self, prot, ctx, message):
if l is None:
l = ctx.in_body_doc[fi.field_name] = []
- l.append(
- File.Value(name=fi.file_name, type=fi.file_type, data=fi.data)
- )
+ l.append(File.Value(name=fi.file_name, type=fi.file_type, data=fi.data))
# this is a huge hack because twisted seems to take the slashes in urls
# too seriously.
- postpath = getattr(request, 'realpostpath', None)
+ postpath = getattr(request, "realpostpath", None)
if postpath is None:
postpath = request.path
if postpath is not None:
postpath = _decode_path(postpath)
- params = self.match_pattern(ctx, request.method, postpath,
- request.getHeader(b'Host'))
+ params = self.match_pattern(
+ ctx, request.method, postpath, request.getHeader(b"Host")
+ )
- if ctx.method_request_string is None: # no pattern match
- ctx.method_request_string = u'{%s}%s' % (
+ if ctx.method_request_string is None: # no pattern match
+ ctx.method_request_string = "{%s}%s" % (
self.app.interface.get_tns(),
- _decode_path(request.path.rsplit(b'/', 1)[-1]).decode("utf8"),
+ _decode_path(request.path.rsplit(b"/", 1)[-1]).decode("utf8"),
)
- logger.debug(u"%sMethod name: %r%s" % (LIGHT_GREEN,
- ctx.method_request_string, END_COLOR))
+ logger.debug(
+ "%sMethod name: %r%s" % (LIGHT_GREEN, ctx.method_request_string, END_COLOR)
+ )
for k, v in params.items():
val = ctx.in_body_doc.get(k, [])
@@ -440,18 +441,13 @@ def decompose_incoming_envelope(self, prot, ctx, message):
ctx.in_body_doc[k] = val
r = {}
- if six.PY2:
- ctx.in_header_doc = self._decode_dict_py2(ctx.in_header_doc)
- ctx.in_body_doc = self._decode_dict_py2(ctx.in_body_doc)
-
- else:
- ctx.in_header_doc = self._decode_dict(ctx.in_header_doc)
- ctx.in_body_doc = self._decode_dict(ctx.in_body_doc)
+ ctx.in_header_doc = self._decode_dict(ctx.in_header_doc)
+ ctx.in_body_doc = self._decode_dict(ctx.in_body_doc)
# This is consistent with what server.wsgi does.
- if request.method in ('POST', 'PUT', 'PATCH'):
+ if request.method in ("POST", "PUT", "PATCH"):
for k, v in ctx.in_body_doc.items():
- if v == ['']:
+ if v == [""]:
ctx.in_body_doc[k] = [None]
logger.debug("%r", ctx.in_body_doc)
@@ -471,14 +467,14 @@ def _get_file_info(ctx):
request = ctx.transport.req
headers = request.getAllHeaders()
- content_type = headers.get('content-type', None)
+ content_type = headers.get("content-type", None)
if content_type is None:
return retval
content = request.content
- content_encoding = headers.get('content-encoding', None)
- if content_encoding == b'gzip':
+ content_encoding = headers.get("content-encoding", None)
+ if content_encoding == b"gzip":
request.content.seek(0)
content = TemporaryFile()
with gzip.GzipFile(fileobj=request.content) as ifstr:
@@ -489,9 +485,9 @@ def _get_file_info(ctx):
fp=content,
headers=ctx.in_header_doc,
environ={
- 'REQUEST_METHOD': request.method,
- 'CONTENT_TYPE': content_type,
- }
+ "REQUEST_METHOD": request.method,
+ "CONTENT_TYPE": content_type,
+ },
)
try:
@@ -507,16 +503,17 @@ def _get_file_info(ctx):
for field in fields:
file_type = field.type
- file_name = field.disposition_options.get('filename', None)
+ file_name = field.disposition_options.get("filename", None)
if file_name is not None:
- retval.append(_FileInfo(k, file_name, file_type,
- [mmap(field.file.fileno(), 0)]))
+ retval.append(
+ _FileInfo(k, file_name, file_type, [mmap(field.file.fileno(), 0)])
+ )
return retval
def _has_fd(istr):
- if not hasattr(istr, 'fileno'):
+ if not hasattr(istr, "fileno"):
return False
try:
istr.fileno()
@@ -531,10 +528,10 @@ def get_twisted_child_with_default(res, path, request):
# http requests too seriously. i.e. it insists that a leaf node can only
# handle the last path fragment.
if res.prepath is None:
- request.realprepath = b'/' + b'/'.join(request.prepath)
+ request.realprepath = b"/" + b"/".join(request.prepath)
else:
- if not res.prepath.startswith(b'/'):
- request.realprepath = b'/' + res.prepath
+ if not res.prepath.startswith(b"/"):
+ request.realprepath = b"/" + res.prepath
else:
request.realprepath = res.prepath
@@ -547,7 +544,8 @@ def get_twisted_child_with_default(res, path, request):
retval = res
else:
request.realpostpath = request.path[
- len(path) + (0 if path.startswith(b'/') else 1):]
+ len(path) + (0 if path.startswith(b"/") else 1) :
+ ]
return retval
@@ -557,13 +555,20 @@ class TwistedWebResource(Resource):
Resource.
"""
- def __init__(self, app, chunked=False, max_content_length=2 * 1024 * 1024,
- block_length=8 * 1024, prepath=None):
+ def __init__(
+ self,
+ app,
+ chunked=False,
+ max_content_length=2 * 1024 * 1024,
+ block_length=8 * 1024,
+ prepath=None,
+ ):
Resource.__init__(self)
self.app = app
- self.http_transport = TwistedHttpTransport(app, chunked,
- max_content_length, block_length)
+ self.http_transport = TwistedHttpTransport(
+ app, chunked, max_content_length, block_length
+ )
self._wsdl = None
self.prepath = prepath
@@ -571,8 +576,9 @@ def getChildWithDefault(self, path, request):
return get_twisted_child_with_default(self, path, request)
def render(self, request):
- if request.method == b'GET' and (
- request.uri.endswith(b'.wsdl') or request.uri.endswith(b'?wsdl')):
+ if request.method == b"GET" and (
+ request.uri.endswith(b".wsdl") or request.uri.endswith(b"?wsdl")
+ ):
return self.__handle_wsdl_request(request)
return self.handle_rpc(request)
@@ -594,7 +600,7 @@ def handle_rpc_error(self, p_ctx, others, error, request):
p_ctx.out_object = error
self.http_transport.get_out_string(p_ctx)
- retval = b''.join(p_ctx.out_string)
+ retval = b"".join(p_ctx.out_string)
p_ctx.close()
@@ -603,15 +609,16 @@ def handle_rpc_error(self, p_ctx, others, error, request):
return retval
def handle_rpc(self, request):
- initial_ctx = TwistedHttpMethodContext(self.http_transport, request,
- self.http_transport.app.out_protocol.mime_type)
+ initial_ctx = TwistedHttpMethodContext(
+ self.http_transport, request, self.http_transport.app.out_protocol.mime_type
+ )
if _has_fd(request.content):
f = request.content
# it's best to avoid empty mappings.
if fstat(f.fileno()).st_size == 0:
- initial_ctx.in_string = ['']
+ initial_ctx.in_string = [""]
else:
initial_ctx.in_string = [mmap(f.fileno(), 0)]
else:
@@ -635,13 +642,11 @@ def handle_rpc(self, request):
self.http_transport.get_in_object(p_ctx)
if p_ctx.in_error:
- return self.handle_rpc_error(p_ctx, others, p_ctx.in_error,
- request)
+ return self.handle_rpc_error(p_ctx, others, p_ctx.in_error, request)
self.http_transport.get_out_object(p_ctx)
if p_ctx.out_error:
- return self.handle_rpc_error(p_ctx, others, p_ctx.out_error,
- request)
+ return self.handle_rpc_error(p_ctx, others, p_ctx.out_error, request)
ret = p_ctx.out_object[0]
retval = NOT_DONE_YET
@@ -655,13 +660,13 @@ def handle_rpc(self, request):
else:
try:
- retval = _cb_deferred(p_ctx.out_object, request, p_ctx, others,
- self, cb=False)
+ retval = _cb_deferred(
+ p_ctx.out_object, request, p_ctx, others, self, cb=False
+ )
except Exception as e:
logger_server.exception(e)
try:
- _eb_deferred(Failure(), request, p_ctx, others,
- resource=self)
+ _eb_deferred(Failure(), request, p_ctx, others, resource=self)
except Exception as e:
logger_server.exception(e)
@@ -672,8 +677,9 @@ def __handle_wsdl_request(self, request):
# logger.debug("WSDL request headers: %r",
# list(request.requestHeaders.getAllRawHeaders()))
- ctx = TwistedHttpMethodContext(self.http_transport, request,
- "text/xml; charset=utf-8")
+ ctx = TwistedHttpMethodContext(
+ self.http_transport, request, "text/xml; charset=utf-8"
+ )
url = _reconstruct_url(request)
if self.http_transport.doc.wsdl11 is None:
@@ -688,18 +694,19 @@ def __handle_wsdl_request(self, request):
try:
if self._wsdl is None:
self.http_transport.doc.wsdl11.build_interface_document(url)
- ctx.transport.wsdl = self._wsdl = \
- self.http_transport.doc.wsdl11.get_interface_document()
+ ctx.transport.wsdl = self._wsdl = (
+ self.http_transport.doc.wsdl11.get_interface_document()
+ )
assert ctx.transport.wsdl is not None
- self.http_transport.event_manager.fire_event('wsdl', ctx)
+ self.http_transport.event_manager.fire_event("wsdl", ctx)
return ctx.transport.wsdl
except Exception as e:
ctx.transport.wsdl_error = e
- self.http_transport.event_manager.fire_event('wsdl_exception', ctx)
+ self.http_transport.event_manager.fire_event("wsdl_exception", ctx)
raise
finally:
@@ -738,7 +745,7 @@ def _cb_deferred(ret, request, p_ctx, others, resource, cb=True):
elif (not issubclass(om, ComplexModelBase)) or len(om._type_info) <= 1:
p_ctx.out_object = [ret]
if len(om._type_info) == 1:
- single_class, = om._type_info.values()
+ (single_class,) = om._type_info.values()
else:
p_ctx.out_object = ret
else:
@@ -750,36 +757,42 @@ def _cb_deferred(ret, request, p_ctx, others, resource, cb=True):
if isinstance(ret, PushBase):
resource.http_transport.init_root_push(ret, p_ctx, others)
- elif ((isclass(om) and issubclass(om, File)) or
- (isclass(single_class) and issubclass(single_class, File))) and \
- isinstance(p_ctx.out_protocol, HttpRpc) and \
- getattr(ret, 'abspath', None) is not None:
-
- file = static.File(ret.abspath,
- defaultType=str(ret.type) or 'application/octet-stream')
+ elif (
+ (
+ (isclass(om) and issubclass(om, File))
+ or (isclass(single_class) and issubclass(single_class, File))
+ )
+ and isinstance(p_ctx.out_protocol, HttpRpc)
+ and getattr(ret, "abspath", None) is not None
+ ):
+
+ file = static.File(
+ ret.abspath, defaultType=str(ret.type) or "application/octet-stream"
+ )
retval = _render_file(file, request)
if retval != NOT_DONE_YET and cb:
request.write(retval)
request.finish()
p_ctx.close()
else:
+
def _close_only_context(ret):
p_ctx.close()
- request.notifyFinish() \
- .addCallback(_close_only_context) \
- .addErrback(_eb_request_finished, request, p_ctx) \
- .addErrback(log_and_let_go, logger)
+ request.notifyFinish().addCallback(_close_only_context).addErrback(
+ _eb_request_finished, request, p_ctx
+ ).addErrback(log_and_let_go, logger)
else:
ret = resource.http_transport.get_out_string(p_ctx)
if not isinstance(ret, Deferred):
producer = Producer(p_ctx.out_string, request)
- producer.deferred \
- .addCallback(_cb_request_finished, request, p_ctx) \
- .addErrback(_eb_request_finished, request, p_ctx) \
- .addErrback(log_and_let_go, logger)
+ producer.deferred.addCallback(
+ _cb_request_finished, request, p_ctx
+ ).addErrback(_eb_request_finished, request, p_ctx).addErrback(
+ log_and_let_go, logger
+ )
try:
request.registerProducer(producer, False)
@@ -792,19 +805,20 @@ def _close_only_context(ret):
raise
else:
+
def _cb(ret):
if isinstance(ret, Deferred):
- return ret \
- .addCallback(_cb) \
- .addErrback(_eb_request_finished, request, p_ctx) \
+ return (
+ ret.addCallback(_cb)
+ .addErrback(_eb_request_finished, request, p_ctx)
.addErrback(log_and_let_go, logger)
+ )
else:
return _cb_request_finished(ret, request, p_ctx)
- ret \
- .addCallback(_cb) \
- .addErrback(_eb_request_finished, request, p_ctx) \
- .addErrback(log_and_let_go, logger)
+ ret.addCallback(_cb).addErrback(
+ _eb_request_finished, request, p_ctx
+ ).addErrback(log_and_let_go, logger)
process_contexts(resource.http_transport, others, p_ctx)
@@ -823,20 +837,20 @@ def _eb_deferred(ret, request, p_ctx, others, resource):
_cb_deferred(None, request, p_ctx, others, resource, cb=False)
- p_ctx.fire_event('method_redirect')
+ p_ctx.fire_event("method_redirect")
except Exception as e:
logger_server.exception(e)
- p_ctx.out_error = Fault('Server', get_fault_string_from_exception(e))
+ p_ctx.out_error = Fault("Server", get_fault_string_from_exception(e))
- p_ctx.fire_event('method_redirect_exception')
+ p_ctx.fire_event("method_redirect_exception")
elif ret.check(Fault):
p_ctx.out_error = ret.value
ret = resource.handle_rpc_error(p_ctx, others, p_ctx.out_error, request)
- p_ctx.fire_event('method_exception_object')
+ p_ctx.fire_event("method_exception_object")
request.write(ret)
@@ -846,7 +860,7 @@ def _eb_deferred(ret, request, p_ctx, others, resource):
ret = resource.handle_rpc_error(p_ctx, others, p_ctx.out_error, request)
- p_ctx.fire_event('method_exception_object')
+ p_ctx.fire_event("method_exception_object")
request.write(ret)
diff --git a/spyne/server/twisted/msgpack.py b/spyne/server/twisted/msgpack.py
index bdabf1416..9a55d93c9 100644
--- a/spyne/server/twisted/msgpack.py
+++ b/spyne/server/twisted/msgpack.py
@@ -20,25 +20,23 @@
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
import io
-
-import msgpack
-
-from time import time
+from collections import OrderedDict, deque
from hashlib import md5
-from collections import deque, OrderedDict
from itertools import chain
+from time import time
+import msgpack
from twisted.internet import reactor
+from twisted.internet.defer import CancelledError, Deferred
+from twisted.internet.protocol import ClientFactory, Factory, Protocol, connectionDone
from twisted.internet.task import deferLater
-from twisted.internet.defer import Deferred, CancelledError
-from twisted.internet.protocol import Protocol, Factory, connectionDone, \
- ClientFactory
from twisted.python.failure import Failure
-from spyne import EventManager, Address, ServerBase, Fault
+from spyne import Address, EventManager, Fault, ServerBase
from spyne.auxproc import process_contexts
from spyne.error import InternalError
from spyne.server.twisted import log_and_let_go
@@ -61,21 +59,22 @@ def buildProtocol(self, address):
return retval
+
TwistedMessagePackProtocolServerFactory = TwistedMessagePackProtocolFactory
class TwistedMessagePackProtocolClientFactory(ClientFactory):
def __init__(self, tpt, max_buffer_size=2 * 1024 * 1024):
- assert isinstance(tpt, ServerBase), \
- "%r is not a ServerBase instance" % tpt
+ assert isinstance(tpt, ServerBase), "%r is not a ServerBase instance" % tpt
self.tpt = tpt
self.max_buffer_size = max_buffer_size
self.event_manager = EventManager(self)
def buildProtocol(self, address):
- return TwistedMessagePackProtocol(self.tpt,
- max_buffer_size=self.max_buffer_size, factory=self)
+ return TwistedMessagePackProtocol(
+ self.tpt, max_buffer_size=self.max_buffer_size, factory=self
+ )
def _cha(*args):
@@ -84,11 +83,18 @@ def _cha(*args):
class TwistedMessagePackProtocol(Protocol):
IDLE_TIMEOUT_SEC = 0
- IDLE_TIMEOUT_MSG = 'idle timeout'
- MAX_INACTIVE_CONTEXTS = float('inf')
-
- def __init__(self, tpt, max_buffer_size=2 * 1024 * 1024, out_chunk_size=0,
- out_chunk_delay_sec=1, max_in_queue_size=0, factory=None):
+ IDLE_TIMEOUT_MSG = "idle timeout"
+ MAX_INACTIVE_CONTEXTS = float("inf")
+
+ def __init__(
+ self,
+ tpt,
+ max_buffer_size=2 * 1024 * 1024,
+ out_chunk_size=0,
+ out_chunk_delay_sec=1,
+ max_in_queue_size=0,
+ factory=None,
+ ):
"""Twisted protocol implementation for Spyne's MessagePack transport.
:param tpt: Spyne transport. It's an app-wide instance.
@@ -106,18 +112,19 @@ def __init__(self, tpt, max_buffer_size=2 * 1024 * 1024, out_chunk_size=0,
"""
from spyne.server.msgpack import MessagePackTransportBase
- assert isinstance(tpt, MessagePackTransportBase), \
- "Expected {!r} got {!r}".format(MessagePackTransportBase, type(tpt))
+
+ assert isinstance(
+ tpt, MessagePackTransportBase
+ ), "Expected {!r} got {!r}".format(MessagePackTransportBase, type(tpt))
self.spyne_tpt = tpt
- self._buffer = msgpack.Unpacker(raw=True,
- max_buffer_size=max_buffer_size)
+ self._buffer = msgpack.Unpacker(raw=True, max_buffer_size=max_buffer_size)
self.out_chunk_size = out_chunk_size
self.out_chunk_delay_sec = out_chunk_delay_sec
self.max_in_queue_size = max_in_queue_size
self.factory = factory
- self.sessid = ''
+ self.sessid = ""
self._delaying = None
self.sent_bytes = 0
self.recv_bytes = 0
@@ -126,7 +133,7 @@ def __init__(self, tpt, max_buffer_size=2 * 1024 * 1024, out_chunk_size=0,
self.inreq_queue = OrderedDict()
self.inactive_queue = deque()
self.disconnecting = False # FIXME: should we use this to raise an
- # invalid connection state exception ?
+ # invalid connection state exception ?
@staticmethod
def gen_chunks(l, n):
@@ -141,22 +148,20 @@ def gen_chunks(l, n):
else:
for i in range(0, len(l), n):
- yield l[i:i+n]
+ yield l[i : i + n]
def gen_sessid(self, *args):
"""It's up to you to use this in a subclass."""
retval = _cha(
- Address.from_twisted_address(self.transport.getPeer()),
- time(),
- *args
+ Address.from_twisted_address(self.transport.getPeer()), time(), *args
)
- return md5(repr(retval).encode('utf8')).hexdigest()
+ return md5(repr(retval).encode("utf8")).hexdigest()
def connectionMade(self):
logger.debug("%08x connection made", id(self))
- self.sessid = ''
+ self.sessid = ""
self._delaying = None
self.sent_bytes = 0
self.recv_bytes = 0
@@ -166,7 +171,7 @@ def connectionMade(self):
self.inactive_queue = deque()
self.active_queue = dict()
self.disconnecting = False # FIXME: should we use this to raise an
- # invalid connection state exception ?
+ # invalid connection state exception ?
self._reset_idle_timer()
if self.factory is not None:
@@ -208,8 +213,7 @@ def dataReceived(self, data):
except Exception as e:
# If you get this error, you are in serious trouble
# This needs to be fixed ASAP
- logger.error(
- "Error %r while processing incoming data %r", e, msg)
+ logger.error("Error %r while processing incoming data %r", e, msg)
raise
if self.disconnecting:
@@ -223,10 +227,16 @@ def _reset_idle_timer(self):
t.cancel()
if self.IDLE_TIMEOUT_SEC is not None and self.IDLE_TIMEOUT_SEC > 0:
- self.idle_timer = deferLater(reactor, self.IDLE_TIMEOUT_SEC,
- self.loseConnection, self.IDLE_TIMEOUT_MSG) \
- .addErrback(self._err_idle_cancelled) \
+ self.idle_timer = (
+ deferLater(
+ reactor,
+ self.IDLE_TIMEOUT_SEC,
+ self.loseConnection,
+ self.IDLE_TIMEOUT_MSG,
+ )
+ .addErrback(self._err_idle_cancelled)
.addErrback(self._err_idle_cancelled_unknown_error)
+ )
def _err_idle_cancelled(self, err):
err.trap(CancelledError)
@@ -234,8 +244,9 @@ def _err_idle_cancelled(self, err):
# do nothing.
def _err_idle_cancelled_unknown_error(self, err):
- logger.error("Sessid %s error cancelling idle timer: %s",
- self.sessid, err.getTraceback())
+ logger.error(
+ "Sessid %s error cancelling idle timer: %s", self.sessid, err.getTraceback()
+ )
self.idle_timer = None
def loseConnection(self, reason=None):
@@ -248,7 +259,8 @@ def process_incoming_message(self, msg, oob=None):
p_ctx, others = self.spyne_tpt.produce_contexts(msg)
p_ctx.oob_ctx = oob
p_ctx.transport.remote_addr = Address.from_twisted_address(
- self.transport.getPeer())
+ self.transport.getPeer()
+ )
p_ctx.transport.protocol = self
p_ctx.transport.sessid = self.sessid
@@ -276,8 +288,10 @@ def process_inactive(self):
self.process_contexts(p_ctx, others)
else:
- while self.num_active_contexts < self.max_in_queue_size and \
- self.num_inactive_contexts > 0:
+ while (
+ self.num_active_contexts < self.max_in_queue_size
+ and self.num_inactive_contexts > 0
+ ):
p_ctx, others = self.inactive_queue.popleft()
self.active_queue[id(p_ctx)] = p_ctx
@@ -285,12 +299,17 @@ def process_inactive(self):
self.process_contexts(p_ctx, others)
if self.num_active_contexts > self.MAX_INACTIVE_CONTEXTS:
- logger.error("%s Too many inactive contexts. "
- "Closing connection.", addr_str)
+ logger.error(
+ "%s Too many inactive contexts. " "Closing connection.", addr_str
+ )
self.loseConnection("Too many inactive contexts")
- logger.debug("%s active %d inactive %d", addr_str,
- self.num_active_contexts, self.num_inactive_contexts)
+ logger.debug(
+ "%s active %d inactive %d",
+ addr_str,
+ self.num_active_contexts,
+ self.num_inactive_contexts,
+ )
def enqueue_outresp_data(self, ctxid, data):
assert self.inreq_queue[ctxid] is None
@@ -301,8 +320,7 @@ def enqueue_outresp_data(self, ctxid, data):
break
self.out_write(v)
- self.spyne_tpt.event_manager.fire_event('outresp_flushed',
- None, k, v)
+ self.spyne_tpt.event_manager.fire_event("outresp_flushed", None, k, v)
del self.inreq_queue[k]
self.active_queue[k].close()
del self.active_queue[k]
@@ -330,8 +348,7 @@ def out_write(self, reqdata):
deferLater(reactor, 0, self._write_single_chunk)
def _wait_for_next_chunk(self):
- return deferLater(reactor, self.out_chunk_delay_sec,
- self._write_single_chunk)
+ return deferLater(reactor, self.out_chunk_delay_sec, self._write_single_chunk)
def _write_single_chunk(self):
try:
@@ -352,12 +369,18 @@ def _write_single_chunk(self):
if self.connected and not self.disconnecting:
self._delaying = self._wait_for_next_chunk()
- logger.debug("%s One chunk of %d bytes written. Delaying "
- "before next chunk write...", self.sessid, len(chunk))
+ logger.debug(
+ "%s One chunk of %d bytes written. Delaying "
+ "before next chunk write...",
+ self.sessid,
+ len(chunk),
+ )
else:
- logger.debug("%s Disconnection detected, discarding "
- "remaining chunks", self.sessid)
+ logger.debug(
+ "%s Disconnection detected, discarding " "remaining chunks",
+ self.sessid,
+ )
self.out_chunks.clear()
def handle_error(self, p_ctx, others, exc):
@@ -373,7 +396,7 @@ def handle_error(self, p_ctx, others, exc):
data = list(data.values())
# tag debug responses with the one from the relevant request
- tag = getattr(p_ctx.transport, 'tag', None)
+ tag = getattr(p_ctx.transport, "tag", None)
if tag is None:
out_object = (error, msgpack.packb(data))
else:
@@ -397,10 +420,11 @@ def handle_error(self, p_ctx, others, exc):
logger.exception(e)
def _register_callbacks(self, d, p_ctx, others):
- return d \
- .addCallback(self._cb_deferred, p_ctx, others) \
- .addErrback(self._eb_deferred, p_ctx, others) \
+ return (
+ d.addCallback(self._cb_deferred, p_ctx, others)
+ .addErrback(self._eb_deferred, p_ctx, others)
.addErrback(log_and_let_go, logger)
+ )
def process_contexts(self, p_ctx, others):
if p_ctx.in_error:
@@ -438,7 +462,7 @@ def _eb_deferred(self, fail, p_ctx, others):
else:
p_ctx.out_error = InternalError(fail.value)
- if not getattr(fail, 'logged', False):
+ if not getattr(fail, "logged", False):
logger.error(fail.getTraceback())
try:
@@ -475,7 +499,7 @@ def _cb_deferred(self, ret, p_ctx, others, nowrap=False):
self.spyne_tpt.get_out_string(p_ctx)
self.spyne_tpt.pack(p_ctx)
- out_string = b''.join(p_ctx.out_string)
+ out_string = b"".join(p_ctx.out_string)
p_ctx.transport.resp_length = len(out_string)
self.enqueue_outresp_data(id(p_ctx), out_string)
diff --git a/spyne/server/twisted/websocket.py b/spyne/server/twisted/websocket.py
index 2e74cabaf..50a74a48f 100644
--- a/spyne/server/twisted/websocket.py
+++ b/spyne/server/twisted/websocket.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -40,31 +39,27 @@
This module is EXPERIMENTAL. Your mileage may vary. Patches are welcome.
"""
-
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Factory
-# FIXME: Switch to:
-# from twisted.web.websockets import WebSocketsProtocol
-# from twisted.web.websockets import WebSocketsResource
-# from twisted.web.websockets import CONTROLS
-
-from spyne.util._twisted_ws import WebSocketsProtocol
-from spyne.util._twisted_ws import WebSocketsResource
-from spyne.util._twisted_ws import CONTROLS
-
-
-from spyne import MethodContext, TransportContext, Address
+from spyne import Address, MethodContext, TransportContext
from spyne.auxproc import process_contexts
from spyne.model import PushBase
from spyne.model.complex import ComplexModel
from spyne.model.fault import Fault
from spyne.server import ServerBase
+from spyne.util._twisted_ws import CONTROLS, WebSocketsProtocol, WebSocketsResource
+
+# FIXME: Switch to:
+# from twisted.web.websockets import WebSocketsProtocol
+# from twisted.web.websockets import WebSocketsResource
+# from twisted.web.websockets import CONTROLS
class WebSocketTransportContext(TransportContext):
@@ -87,8 +82,7 @@ class WebSocketMethodContext(MethodContext):
def __init__(self, transport, client_handle):
MethodContext.__init__(self, transport, MethodContext.SERVER)
- self.transport = WebSocketTransportContext(self, transport, 'ws',
- client_handle)
+ self.transport = WebSocketTransportContext(self, transport, "ws", client_handle)
class TwistedWebSocketProtocol(WebSocketsProtocol):
@@ -124,7 +118,6 @@ def _connectionMade(self):
def _connectionLost(self, reason):
del self._clients[id(self)]
-
def frameReceived(self, opcode, data, fin):
tpt = self._spyne_transport
@@ -155,7 +148,7 @@ def _cb_deferred(retval, cb=True):
p_ctx.out_object = retval
tpt.get_out_string(p_ctx)
- self.sendFrame(opcode, ''.join(p_ctx.out_string), fin)
+ self.sendFrame(opcode, "".join(p_ctx.out_string), fin)
p_ctx.close()
process_contexts(tpt, others, p_ctx)
@@ -165,7 +158,7 @@ def _eb_deferred(err):
logger.error(err.getTraceback())
tpt.get_out_string(p_ctx)
- self.sendFrame(opcode, ''.join(p_ctx.out_string), fin)
+ self.sendFrame(opcode, "".join(p_ctx.out_string), fin)
p_ctx.close()
ret = p_ctx.out_object
@@ -193,8 +186,8 @@ def __init__(self, app, bookkeep=False, _clients=None):
self._clients = {}
def buildProtocol(self, addr):
- return TwistedWebSocketProtocol(self.transport, self.bookkeep,
- self._clients)
+ return TwistedWebSocketProtocol(self.transport, self.bookkeep, self._clients)
+
class _Fake(object):
pass
@@ -229,12 +222,14 @@ def __init__(self, app, bookkeep=False, clients=None):
if bookkeep:
self.propagate = self.do_propagate
- WebSocketsResource.__init__(self, TwistedWebSocketFactory(app,
- bookkeep, self.clients))
+ WebSocketsResource.__init__(
+ self, TwistedWebSocketFactory(app, bookkeep, self.clients)
+ )
def propagate(self):
- raise InvalidRequestError("You must enable bookkeeping to have "
- "message propagation work.")
+ raise InvalidRequestError(
+ "You must enable bookkeeping to have " "message propagation work."
+ )
def get_doc(self, obj, cls=None):
if cls is None:
@@ -245,11 +240,11 @@ def get_doc(self, obj, cls=None):
op.serialize(ctx, op.RESPONSE)
op.create_out_string(ctx)
- return ''.join(ctx.out_string)
+ return "".join(ctx.out_string)
def do_propagate(self, obj, cls=None):
doc = self.get_doc(obj, cls)
for c in self.clients.itervalues():
- print('sending to', c)
+ print("sending to", c)
c.sendFrame(CONTROLS.TEXT, doc, True)
diff --git a/spyne/server/wsgi.py b/spyne/server/wsgi.py
index 6275ae404..3e344fa5e 100644
--- a/spyne/server/wsgi.py
+++ b/spyne/server/wsgi.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -23,39 +22,35 @@
logic.
"""
-
import logging
+
logger = logging.getLogger(__name__)
import threading
-
+from http.cookies import SimpleCookie
from inspect import isgenerator
from itertools import chain
+from urllib.parse import quote, unquote
-from spyne import Address, File, Fault
-from spyne.util.six.moves.http_cookies import SimpleCookie
-from spyne.util.six.moves.urllib.parse import unquote, quote
-
+from spyne._base import Address
from spyne.application import get_fault_string_from_exception
from spyne.auxproc import process_contexts
+from spyne.const.ansi_color import END_COLOR, LIGHT_GREEN
+from spyne.const.http import HTTP_200, HTTP_404, HTTP_500
from spyne.error import RequestTooLongError
+from spyne.model.binary import File
+from spyne.model.fault import Fault
from spyne.protocol.http import HttpRpc
from spyne.server.http import HttpBase, HttpMethodContext, HttpTransportContext
-from spyne.util.odict import odict
from spyne.util.address import address_parser
from spyne.util.http import parse_content_type_header
-
-from spyne.const.ansi_color import LIGHT_GREEN
-from spyne.const.ansi_color import END_COLOR
-from spyne.const.http import HTTP_200
-from spyne.const.http import HTTP_404
-from spyne.const.http import HTTP_500
-
+from spyne.util.odict import odict
try:
from spyne.protocol.soap.mime import apply_mtom
except ImportError as _import_error_1:
_local_import_error_1 = _import_error_1 # python 3 workaround
+
def apply_mtom(*args, **kwargs):
raise _local_import_error_1
@@ -64,12 +59,14 @@ def apply_mtom(*args, **kwargs):
from werkzeug.formparser import parse_form_data
except ImportError as _import_error_2:
_local_import_error_2 = _import_error_2 # python 3 workaround
+
def parse_form_data(*args, **kwargs):
raise _local_import_error_2
-def _reconstruct_url(environ, protocol=True, server_name=True, path=True,
- query_string=True):
+def _reconstruct_url(
+ environ, protocol=True, server_name=True, path=True, query_string=True
+):
"""Rebuilds the calling url from values found in the
environment.
@@ -77,64 +74,66 @@ def _reconstruct_url(environ, protocol=True, server_name=True, path=True,
contributed by Ian Bicking.
"""
- url = ''
+ url = ""
if protocol:
- url = environ['wsgi.url_scheme'] + '://'
+ url = environ["wsgi.url_scheme"] + "://"
if server_name:
- if environ.get('HTTP_HOST'):
- url += environ['HTTP_HOST']
+ if environ.get("HTTP_HOST"):
+ url += environ["HTTP_HOST"]
else:
- url += environ['SERVER_NAME']
+ url += environ["SERVER_NAME"]
- if environ['wsgi.url_scheme'] == 'https':
- if environ['SERVER_PORT'] != '443':
- url += ':' + environ['SERVER_PORT']
+ if environ["wsgi.url_scheme"] == "https":
+ if environ["SERVER_PORT"] != "443":
+ url += ":" + environ["SERVER_PORT"]
else:
- if environ['SERVER_PORT'] != '80':
- url += ':' + environ['SERVER_PORT']
+ if environ["SERVER_PORT"] != "80":
+ url += ":" + environ["SERVER_PORT"]
if path:
- if (quote(environ.get('SCRIPT_NAME', '')) == '/' and
- quote(environ.get('PATH_INFO', ''))[0] == '/'):
- #skip this if it is only a slash
+ if (
+ quote(environ.get("SCRIPT_NAME", "")) == "/"
+ and quote(environ.get("PATH_INFO", ""))[0] == "/"
+ ):
+ # skip this if it is only a slash
pass
- elif quote(environ.get('SCRIPT_NAME', ''))[0:2] == '//':
- url += quote(environ.get('SCRIPT_NAME', ''))[1:]
+ elif quote(environ.get("SCRIPT_NAME", ""))[0:2] == "//":
+ url += quote(environ.get("SCRIPT_NAME", ""))[1:]
else:
- url += quote(environ.get('SCRIPT_NAME', ''))
+ url += quote(environ.get("SCRIPT_NAME", ""))
- url += quote(environ.get('PATH_INFO', ''))
+ url += quote(environ.get("PATH_INFO", ""))
if query_string:
- if environ.get('QUERY_STRING'):
- url += '?' + environ['QUERY_STRING']
+ if environ.get("QUERY_STRING"):
+ url += "?" + environ["QUERY_STRING"]
return url
def _parse_qs(qs):
- pairs = (s2 for s1 in qs.split('&') for s2 in s1.split(';'))
+ pairs = (s2 for s1 in qs.split("&") for s2 in s1.split(";"))
retval = odict()
for name_value in pairs:
if name_value is None or len(name_value) == 0:
continue
- nv = name_value.split('=', 1)
+ nv = name_value.split("=", 1)
if len(nv) != 2:
# Handle case of a control-name with no equal sign
nv.append(None)
- name = unquote(nv[0].replace('+', ' '))
+ name = unquote(nv[0].replace("+", " "))
value = None
if nv[1] is not None:
- value = unquote(nv[1].replace('+', ' '))
+ value = unquote(nv[1].replace("+", " "))
l = retval.get(name, None)
if l is None:
@@ -151,7 +150,7 @@ def _get_http_headers(req_env):
if k.startswith("HTTP_"):
key = k[5:].lower()
val = [v]
- retval[key]= val
+ retval[key] = val
logger.debug("Add http header %r = %r", key, val)
return retval
@@ -160,7 +159,7 @@ def _get_http_headers(req_env):
def _gen_http_headers(headers):
retval = []
- for k,v in headers.items():
+ for k, v in headers.items():
if isinstance(v, (list, tuple)):
for v2 in v:
retval.append((k, v2))
@@ -175,13 +174,14 @@ class WsgiTransportContext(HttpTransportContext):
:class:`WsgiMethodContext` class."""
def __init__(self, parent, transport, req_env, content_type):
- super(WsgiTransportContext, self).__init__(parent, transport,
- req_env, content_type)
+ super(WsgiTransportContext, self).__init__(
+ parent, transport, req_env, content_type
+ )
self.req_env = self.req
"""WSGI Request environment"""
- self.req_method = req_env.get('REQUEST_METHOD', None)
+ self.req_method = req_env.get("REQUEST_METHOD", None)
"""HTTP Request verb, as a convenience to users."""
self.headers = _get_http_headers(self.req_env)
@@ -190,17 +190,17 @@ def get_url(self):
return _reconstruct_url(self.req_env)
def get_path(self):
- return self.req_env['PATH_INFO']
+ return self.req_env["PATH_INFO"]
def get_path_and_qs(self):
- retval = quote(self.req_env.get('PATH_INFO', ''))
- qs = self.req_env.get('QUERY_STRING', None)
+ retval = quote(self.req_env.get("PATH_INFO", ""))
+ qs = self.req_env.get("QUERY_STRING", None)
if qs is not None:
- retval += '?' + qs
+ retval += "?" + qs
return retval
def get_cookie(self, key):
- cookie_string = self.req_env.get('HTTP_COOKIE', None)
+ cookie_string = self.req_env.get("HTTP_COOKIE", None)
if cookie_string is None:
return
@@ -210,14 +210,13 @@ def get_cookie(self, key):
return cookie.get(key, None).value
def get_request_method(self):
- return self.req['REQUEST_METHOD'].upper()
+ return self.req["REQUEST_METHOD"].upper()
def get_request_content_type(self):
return self.req.get("CONTENT_TYPE", None)
def get_peer(self):
- addr, port = address_parser.get_ip(self.req),\
- address_parser.get_port(self.req)
+ addr, port = address_parser.get_ip(self.req), address_parser.get_port(self.req)
if address_parser.is_valid_ipv4(addr):
return Address(type=Address.TCP4, host=addr, port=port)
@@ -279,10 +278,16 @@ class WsgiApplication(HttpBase):
called both from success and error cases.
"""
- def __init__(self, app, chunked=True, max_content_length=2 * 1024 * 1024,
- block_length=8 * 1024):
- super(WsgiApplication, self).__init__(app, chunked, max_content_length,
- block_length)
+ def __init__(
+ self,
+ app,
+ chunked=True,
+ max_content_length=2 * 1024 * 1024,
+ block_length=8 * 1024,
+ ):
+ super(WsgiApplication, self).__init__(
+ app, chunked, max_content_length, block_length
+ )
self._mtx_build_interface_document = threading.Lock()
@@ -299,11 +304,11 @@ def __call__(self, req_env, start_response, wsgi_url=None):
url = wsgi_url
if url is None:
- url = _reconstruct_url(req_env).split('.wsdl')[0]
+ url = _reconstruct_url(req_env).split(".wsdl")[0]
if self.is_wsdl_request(req_env):
# Format the url for location
- url = url.split('?')[0].split('.wsdl')[0]
+ url = url.split("?")[0].split(".wsdl")[0]
return self.handle_wsdl_request(req_env, start_response, url)
else:
@@ -314,23 +319,19 @@ def is_wsdl_request(self, req_env):
# /stuff/stuff/stuff/serviceName.wsdl or
# /stuff/stuff/stuff/serviceName/?wsdl
- return (
- req_env['REQUEST_METHOD'].upper() == 'GET'
- and (
- (
- 'QUERY_STRING' in req_env
- and req_env['QUERY_STRING'].split('=')[0].lower() == 'wsdl'
- )
- or req_env['PATH_INFO'].endswith('.wsdl')
+ return req_env["REQUEST_METHOD"].upper() == "GET" and (
+ (
+ "QUERY_STRING" in req_env
+ and req_env["QUERY_STRING"].split("=")[0].lower() == "wsdl"
)
+ or req_env["PATH_INFO"].endswith(".wsdl")
)
def handle_wsdl_request(self, req_env, start_response, url):
- ctx = WsgiMethodContext(self, req_env, 'text/xml; charset=utf-8')
+ ctx = WsgiMethodContext(self, req_env, "text/xml; charset=utf-8")
if self.doc.wsdl11 is None:
- start_response(HTTP_404,
- _gen_http_headers(ctx.transport.resp_headers))
+ start_response(HTTP_404, _gen_http_headers(ctx.transport.resp_headers))
return [HTTP_404]
if self._wsdl is None:
@@ -346,27 +347,26 @@ def handle_wsdl_request(self, req_env, start_response, url):
if ctx.transport.wsdl is None:
self.doc.wsdl11.build_interface_document(url)
- ctx.transport.wsdl = self._wsdl = \
- self.doc.wsdl11.get_interface_document()
+ ctx.transport.wsdl = self._wsdl = (
+ self.doc.wsdl11.get_interface_document()
+ )
except Exception as e:
logger.exception(e)
ctx.transport.wsdl_error = e
- self.event_manager.fire_event('wsdl_exception', ctx)
+ self.event_manager.fire_event("wsdl_exception", ctx)
- start_response(HTTP_500,
- _gen_http_headers(ctx.transport.resp_headers))
+ start_response(HTTP_500, _gen_http_headers(ctx.transport.resp_headers))
return [HTTP_500]
finally:
self._mtx_build_interface_document.release()
- self.event_manager.fire_event('wsdl', ctx)
+ self.event_manager.fire_event("wsdl", ctx)
- ctx.transport.resp_headers['Content-Length'] = \
- str(len(ctx.transport.wsdl))
+ ctx.transport.resp_headers["Content-Length"] = str(len(ctx.transport.wsdl))
start_response(HTTP_200, _gen_http_headers(ctx.transport.resp_headers))
retval = ctx.transport.wsdl
@@ -385,20 +385,23 @@ def handle_error(self, p_ctx, others, error, start_response):
"""
if p_ctx.transport.resp_code is None:
- p_ctx.transport.resp_code = \
- p_ctx.out_protocol.fault_to_http_response_code(error)
+ p_ctx.transport.resp_code = p_ctx.out_protocol.fault_to_http_response_code(
+ error
+ )
self.get_out_string(p_ctx)
# consume the generator to get the length
p_ctx.out_string = list(p_ctx.out_string)
- p_ctx.transport.resp_headers['Content-Length'] = \
- str(sum((len(s) for s in p_ctx.out_string)))
- self.event_manager.fire_event('wsgi_exception', p_ctx)
+ p_ctx.transport.resp_headers["Content-Length"] = str(
+ sum((len(s) for s in p_ctx.out_string))
+ )
+ self.event_manager.fire_event("wsgi_exception", p_ctx)
- start_response(p_ctx.transport.resp_code,
- _gen_http_headers(p_ctx.transport.resp_headers))
+ start_response(
+ p_ctx.transport.resp_code, _gen_http_headers(p_ctx.transport.resp_headers)
+ )
try:
process_contexts(self, others, p_ctx, error=error)
@@ -409,12 +412,12 @@ def handle_error(self, p_ctx, others, error, start_response):
return chain(p_ctx.out_string, self.__finalize(p_ctx))
def handle_rpc(self, req_env, start_response):
- initial_ctx = WsgiMethodContext(self, req_env,
- self.app.out_protocol.mime_type)
+ initial_ctx = WsgiMethodContext(self, req_env, self.app.out_protocol.mime_type)
- self.event_manager.fire_event('wsgi_call', initial_ctx)
- initial_ctx.in_string, in_string_charset = \
- self.__reconstruct_wsgi_request(req_env)
+ self.event_manager.fire_event("wsgi_call", initial_ctx)
+ initial_ctx.in_string, in_string_charset = self.__reconstruct_wsgi_request(
+ req_env
+ )
contexts = self.generate_contexts(initial_ctx, in_string_charset)
p_ctx, others = contexts[0], contexts[1:]
@@ -423,19 +426,16 @@ def handle_rpc(self, req_env, start_response):
p_ctx.active = True
if p_ctx.in_error:
- return self.handle_error(p_ctx, others, p_ctx.in_error,
- start_response)
+ return self.handle_error(p_ctx, others, p_ctx.in_error, start_response)
self.get_in_object(p_ctx)
if p_ctx.in_error:
logger.error(p_ctx.in_error)
- return self.handle_error(p_ctx, others, p_ctx.in_error,
- start_response)
+ return self.handle_error(p_ctx, others, p_ctx.in_error, start_response)
self.get_out_object(p_ctx)
if p_ctx.out_error:
- return self.handle_error(p_ctx, others, p_ctx.out_error,
- start_response)
+ return self.handle_error(p_ctx, others, p_ctx.out_error, start_response)
assert p_ctx.out_object is not None
g = next(iter(p_ctx.out_object))
@@ -448,7 +448,7 @@ def handle_rpc(self, req_env, start_response):
# protocol. Is there a better way?
if is_generator:
first_obj = next(g)
- p_ctx.out_object = ( chain((first_obj,), g), )
+ p_ctx.out_object = (chain((first_obj,), g),)
if p_ctx.transport.resp_code is None:
p_ctx.transport.resp_code = HTTP_200
@@ -458,13 +458,10 @@ def handle_rpc(self, req_env, start_response):
except Exception as e:
logger.exception(e)
- p_ctx.out_error = Fault('Server', get_fault_string_from_exception(e))
- return self.handle_error(p_ctx, others, p_ctx.out_error,
- start_response)
+ p_ctx.out_error = Fault("Server", get_fault_string_from_exception(e))
+ return self.handle_error(p_ctx, others, p_ctx.out_error, start_response)
-
- if isinstance(p_ctx.out_protocol, HttpRpc) and \
- p_ctx.out_header_doc is not None:
+ if isinstance(p_ctx.out_protocol, HttpRpc) and p_ctx.out_header_doc is not None:
p_ctx.transport.resp_headers.update(p_ctx.out_header_doc)
if p_ctx.descriptor and p_ctx.descriptor.mtom:
@@ -478,31 +475,34 @@ def handle_rpc(self, req_env, start_response):
p_ctx.out_object = [p_ctx.out_object]
p_ctx.transport.resp_headers, p_ctx.out_string = apply_mtom(
- p_ctx.transport.resp_headers, p_ctx.out_string,
- p_ctx.descriptor.out_message._type_info.values(),
- p_ctx.out_object,
- )
+ p_ctx.transport.resp_headers,
+ p_ctx.out_string,
+ p_ctx.descriptor.out_message._type_info.values(),
+ p_ctx.out_object,
+ )
- self.event_manager.fire_event('wsgi_return', p_ctx)
+ self.event_manager.fire_event("wsgi_return", p_ctx)
if self.chunked:
# the user has not set a content-length, so we delete it as the
# input is just an iterable.
- if 'Content-Length' in p_ctx.transport.resp_headers:
- del p_ctx.transport.resp_headers['Content-Length']
+ if "Content-Length" in p_ctx.transport.resp_headers:
+ del p_ctx.transport.resp_headers["Content-Length"]
else:
- p_ctx.out_string = [''.join(p_ctx.out_string)]
+ p_ctx.out_string = ["".join(p_ctx.out_string)]
try:
len(p_ctx.out_string)
- p_ctx.transport.resp_headers['Content-Length'] = \
- str(sum([len(a) for a in p_ctx.out_string]))
+ p_ctx.transport.resp_headers["Content-Length"] = str(
+ sum([len(a) for a in p_ctx.out_string])
+ )
except TypeError:
pass
- start_response(p_ctx.transport.resp_code,
- _gen_http_headers(p_ctx.transport.resp_headers))
+ start_response(
+ p_ctx.transport.resp_code, _gen_http_headers(p_ctx.transport.resp_headers)
+ )
retval = chain(p_ctx.out_string, self.__finalize(p_ctx))
@@ -516,7 +516,7 @@ def handle_rpc(self, req_env, start_response):
def __finalize(self, p_ctx):
p_ctx.close()
- self.event_manager.fire_event('wsgi_close', p_ctx)
+ self.event_manager.fire_event("wsgi_close", p_ctx)
return ()
@@ -530,14 +530,14 @@ def __reconstruct_wsgi_request(self, http_env):
# >>> parse_content_type_header("text/xml; charset=utf-8")
# ('text/xml', {'charset': 'utf-8'})
content_type = parse_content_type_header(content_type)
- charset = content_type[1].get('charset', None)
+ charset = content_type[1].get("charset", None)
return self.__wsgi_input_to_iterable(http_env), charset
def __wsgi_input_to_iterable(self, http_env):
- istream = http_env.get('wsgi.input')
+ istream = http_env.get("wsgi.input")
- length = str(http_env.get('CONTENT_LENGTH', self.max_content_length))
+ length = str(http_env.get("CONTENT_LENGTH", self.max_content_length))
if len(length) == 0:
length = 0
else:
@@ -571,39 +571,43 @@ def decompose_incoming_envelope(self, prot, ctx, message):
if self.has_patterns:
# http://legacy.python.org/dev/peps/pep-0333/#url-reconstruction
- domain = wsgi_env.get('HTTP_HOST', None)
+ domain = wsgi_env.get("HTTP_HOST", None)
if domain is None:
- domain = wsgi_env['SERVER_NAME']
+ domain = wsgi_env["SERVER_NAME"]
else:
- domain = domain.partition(':')[0] # strip port info
+ domain = domain.partition(":")[0] # strip port info
- params = self.match_pattern(ctx,
- wsgi_env.get('REQUEST_METHOD', ''),
- wsgi_env.get('PATH_INFO', ''),
- domain,
- )
+ params = self.match_pattern(
+ ctx,
+ wsgi_env.get("REQUEST_METHOD", ""),
+ wsgi_env.get("PATH_INFO", ""),
+ domain,
+ )
if ctx.method_request_string is None:
- ctx.method_request_string = '{%s}%s' % (
- prot.app.interface.get_tns(),
- wsgi_env['PATH_INFO'].split('/')[-1])
+ ctx.method_request_string = "{%s}%s" % (
+ prot.app.interface.get_tns(),
+ wsgi_env["PATH_INFO"].split("/")[-1],
+ )
- logger.debug("%sMethod name: %r%s" % (LIGHT_GREEN,
- ctx.method_request_string, END_COLOR))
+ logger.debug(
+ "%sMethod name: %r%s" % (LIGHT_GREEN, ctx.method_request_string, END_COLOR)
+ )
ctx.in_header_doc = ctx.transport.headers
- ctx.in_body_doc = _parse_qs(wsgi_env['QUERY_STRING'])
+ ctx.in_body_doc = _parse_qs(wsgi_env["QUERY_STRING"])
for k, v in params.items():
- if k in ctx.in_body_doc:
- ctx.in_body_doc[k].extend(v)
- else:
- ctx.in_body_doc[k] = list(v)
+ if k in ctx.in_body_doc:
+ ctx.in_body_doc[k].extend(v)
+ else:
+ ctx.in_body_doc[k] = list(v)
- verb = wsgi_env['REQUEST_METHOD'].upper()
- if verb in ('POST', 'PUT', 'PATCH'):
- stream, form, files = parse_form_data(wsgi_env,
- stream_factory=prot.stream_factory)
+ verb = wsgi_env["REQUEST_METHOD"].upper()
+ if verb in ("POST", "PUT", "PATCH"):
+ stream, form, files = parse_form_data(
+ wsgi_env, stream_factory=prot.stream_factory
+ )
for k, v in form.lists():
val = ctx.in_body_doc.get(k, [])
@@ -613,20 +617,25 @@ def decompose_incoming_envelope(self, prot, ctx, message):
for k, v in files.items():
val = ctx.in_body_doc.get(k, [])
- mime_type = v.headers.get('Content-Type',
- 'application/octet-stream')
+ mime_type = v.headers.get("Content-Type", "application/octet-stream")
- path = getattr(v.stream, 'name', None)
+ path = getattr(v.stream, "name", None)
if path is None:
- val.append(File.Value(name=v.filename, type=mime_type,
- data=[v.stream.getvalue()]))
+ val.append(
+ File.Value(
+ name=v.filename, type=mime_type, data=[v.stream.getvalue()]
+ )
+ )
else:
v.stream.seek(0)
- val.append(File.Value(name=v.filename, type=mime_type,
- path=path, handle=v.stream))
+ val.append(
+ File.Value(
+ name=v.filename, type=mime_type, path=path, handle=v.stream
+ )
+ )
ctx.in_body_doc[k] = val
for k, v in ctx.in_body_doc.items():
- if v == ['']:
+ if v == [""]:
ctx.in_body_doc[k] = [None]
diff --git a/spyne/server/zeromq.py b/spyne/server/zeromq.py
index f897d55ca..70890fd95 100644
--- a/spyne/server/zeromq.py
+++ b/spyne/server/zeromq.py
@@ -19,6 +19,7 @@
"""The ``spyne.server.zeromq`` module contains a server implementation that
uses ZeroMQ (zmq.REP) as transport.
"""
+
import threading
import zmq
@@ -31,12 +32,13 @@
class ZmqMethodContext(MethodContext):
def __init__(self, app):
super(ZmqMethodContext, self).__init__(app, MethodContext.SERVER)
- self.transport.type = 'zmq'
+ self.transport.type = "zmq"
class ZeroMQServer(ServerBase):
"""The ZeroMQ server transport."""
- transport = 'http://rfc.zeromq.org/'
+
+ transport = "http://rfc.zeromq.org/"
def __init__(self, app, app_url, wsdl_url=None, ctx=None, socket=None):
if ctx and socket and ctx is not socket.context:
@@ -63,9 +65,10 @@ def __handle_wsdl_request(self):
return self.app.get_interface_document(self.url)
# FIXME: Add suport for binary-only transports
- def generate_contexts(self, ctx, in_string_charset='utf8'):
- return super(ZeroMQServer, self).generate_contexts(ctx,
- in_string_charset=in_string_charset)
+ def generate_contexts(self, ctx, in_string_charset="utf8"):
+ return super(ZeroMQServer, self).generate_contexts(
+ ctx, in_string_charset=in_string_charset
+ )
def serve_forever(self):
"""Runs the ZeroMQ server."""
@@ -102,7 +105,7 @@ def serve_forever(self):
process_contexts(self, others, error)
- self.zmq_socket.send(b''.join(p_ctx.out_string))
+ self.zmq_socket.send(b"".join(p_ctx.out_string))
p_ctx.close()
@@ -111,7 +114,8 @@ class ZeroMQThreadPoolServer(object):
"""Create a ZeroMQ server transport with several background workers,
allowing asynchronous calls.
- More details on the pattern http://zguide.zeromq.org/page:all#Shared-Queue-DEALER-and-ROUTER-sockets"""
+ More details on the pattern http://zguide.zeromq.org/page:all#Shared-Queue-DEALER-and-ROUTER-sockets
+ """
def __init__(self, app, app_url, pool_size, wsdl_url=None, ctx=None, socket=None):
if ctx and socket and ctx is not socket.context:
@@ -132,7 +136,7 @@ def __init__(self, app, app_url, pool_size, wsdl_url=None, ctx=None, socket=None
self.frontend = self.ctx.socket(zmq.ROUTER)
self.frontend.bind(app_url)
- be_url = 'inproc://{tns}.{name}'.format(tns=self.app.tns, name=self.app.name)
+ be_url = "inproc://{tns}.{name}".format(tns=self.app.tns, name=self.app.name)
self.pool = []
self.background_jobs = []
for i in range(pool_size):
diff --git a/spyne/service.py b/spyne/service.py
index 5b02c3abe..ca337bde0 100644
--- a/spyne/service.py
+++ b/spyne/service.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -22,12 +21,12 @@
"""
import logging
+
logger = logging.getLogger(__name__)
-from spyne.util.six.moves.collections_abc import Sequence
+from collections.abc import Sequence
from spyne.evmgr import EventManager
-from spyne.util import six
from spyne.util.oset import oset
@@ -38,14 +37,15 @@ def __init__(self, cls_name, cls_bases, cls_dict):
super(ServiceBaseMeta, self).__init__(cls_name, cls_bases, cls_dict)
self.public_methods = {}
- self.event_manager = EventManager(self,
- self.__get_base_event_handlers(cls_bases))
+ self.event_manager = EventManager(
+ self, self.__get_base_event_handlers(cls_bases)
+ )
def __get_base_event_handlers(self, cls_bases):
handlers = {}
for base in cls_bases:
- evmgr = getattr(base, 'event_manager', None)
+ evmgr = getattr(base, "event_manager", None)
if evmgr is None:
continue
@@ -57,6 +57,7 @@ def __get_base_event_handlers(self, cls_bases):
return handlers
+
class ServiceMeta(ServiceBaseMeta):
"""Creates the :class:`spyne.MethodDescriptor` objects by iterating over
tagged methods.
@@ -69,7 +70,7 @@ def __init__(self, cls_name, cls_bases, cls_dict):
has_nonaux_methods = None
for k, v in cls_dict.items():
- if not hasattr(v, '_is_rpc'):
+ if not hasattr(v, "_is_rpc"):
continue
descriptor = v(_default_function_name=k, _service_class=self)
@@ -92,16 +93,17 @@ def __init__(self, cls_name, cls_bases, cls_dict):
self.__has_aux_methods = True
if self.__has_aux_methods and has_nonaux_methods:
- raise Exception("You can't mix primary and "
- "auxiliary methods in a single service definition.")
+ raise Exception(
+ "You can't mix primary and "
+ "auxiliary methods in a single service definition."
+ )
def is_auxiliary(self):
return self.__has_aux_methods
# FIXME: To be renamed to ServiceBase in Spyne 3
-@six.add_metaclass(ServiceBaseMeta)
-class ServiceBaseBase(object):
+class ServiceBaseBase(metaclass=ServiceBaseMeta):
__in_header__ = None
"""The incoming header object that the methods under this service definition
accept."""
@@ -182,7 +184,7 @@ def call_wrapper(cls, ctx, args=None):
if args is None:
args = ctx.in_object
- assert not isinstance(args, six.string_types)
+ assert not isinstance(args, str)
# python3 wants a proper sequence as *args
if not isinstance(args, Sequence):
@@ -198,8 +200,7 @@ def initialize(cls, app):
pass
-@six.add_metaclass(ServiceMeta)
-class Service(ServiceBaseBase):
+class Service(ServiceBaseBase, metaclass=ServiceMeta):
"""The ``Service`` class is the base class for all service definitions.
The convention is to have public methods defined under a subclass of this
diff --git a/spyne/store/__init__.py b/spyne/store/__init__.py
index c597ee328..01ae947be 100644
--- a/spyne/store/__init__.py
+++ b/spyne/store/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
diff --git a/spyne/store/relational/__init__.py b/spyne/store/relational/__init__.py
index 642d3f354..014d321b5 100644
--- a/spyne/store/relational/__init__.py
+++ b/spyne/store/relational/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -22,14 +21,21 @@
Uses SQLAlchemy for mapping objects to relations.
"""
-from spyne.store.relational._base import add_column
-from spyne.store.relational._base import gen_sqla_info
-from spyne.store.relational._base import gen_spyne_info
-from spyne.store.relational._base import get_pk_columns
-
-from spyne.store.relational.document import PGXml, PGObjectXml, PGHtml, \
- PGJson, PGJsonB, PGObjectJson, PGFileJson
-from spyne.store.relational.simple import PGLTree, PGLQuery, PGLTxtQuery
-from spyne.store.relational.spatial import PGGeometry
-
from spyne.store.relational import override
+from spyne.store.relational._base import (
+ add_column,
+ gen_spyne_info,
+ gen_sqla_info,
+ get_pk_columns,
+)
+from spyne.store.relational.document import (
+ PGFileJson,
+ PGHtml,
+ PGJson,
+ PGJsonB,
+ PGObjectJson,
+ PGObjectXml,
+ PGXml,
+)
+from spyne.store.relational.simple import PGLQuery, PGLTree, PGLTxtQuery
+from spyne.store.relational.spatial import PGGeometry
diff --git a/spyne/store/relational/_base.py b/spyne/store/relational/_base.py
index 66fca3219..ad909f177 100644
--- a/spyne/store/relational/_base.py
+++ b/spyne/store/relational/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -21,6 +20,7 @@
from __future__ import absolute_import, print_function
import logging
+
logger = logging.getLogger(__name__)
import sqlalchemy
@@ -30,61 +30,87 @@
except ImportError:
import json
-from os.path import isabs
from inspect import isclass
+from os.path import isabs
from sqlalchemy import event
-from sqlalchemy.schema import Column
-from sqlalchemy.schema import Index
-from sqlalchemy.schema import Table
-from sqlalchemy.schema import ForeignKey
-
-from sqlalchemy.dialects.postgresql import FLOAT
-from sqlalchemy.dialects.postgresql import DOUBLE_PRECISION
-from sqlalchemy.dialects.postgresql.base import PGUuid, PGInet
-
-from sqlalchemy.orm import relationship
-from sqlalchemy.orm import mapper
+from sqlalchemy.dialects.postgresql import DOUBLE_PRECISION, FLOAT
+from sqlalchemy.dialects.postgresql.base import PGInet, PGUuid
from sqlalchemy.ext.associationproxy import association_proxy
+from sqlalchemy.orm import registry as _registry
+from sqlalchemy.orm import relationship
-# TODO: find the latest way of checking whether a class is already mapped
-try:
- from sqlalchemy.orm import mapperlib
- _mapper_registries = mapperlib._mapper_registries
-
-except (ImportError, AttributeError):
- from sqlalchemy.orm import _mapper_registry as _mapper_registries
-
-from spyne.store.relational.simple import PGLTree
-from spyne.store.relational.document import PGXml, PGObjectXml, PGObjectJson, \
- PGFileJson, PGJsonB, PGHtml, PGJson
-from spyne.store.relational.spatial import PGGeometry
-
-# internal types
-from spyne.model.enum import EnumBase
-from spyne.model.complex import XmlModifier
+_mapper_registry = _registry()
+from sqlalchemy import inspect as sa_inspect
+from sqlalchemy.exc import NoInspectionAvailable
+from sqlalchemy.schema import Column, ForeignKey, Index, Table
+# public types
# Config types
-from spyne.model import xml as c_xml
+from spyne.model import (
+ Any,
+ AnyDict,
+ AnyHtml,
+ AnyXml,
+ Array,
+ Boolean,
+ ByteArray,
+ ComplexModelBase,
+ Date,
+ DateTime,
+ Decimal,
+ Double,
+ Duration,
+ Enum,
+ File,
+ Float,
+ Integer,
+ Integer8,
+ Integer16,
+ Integer32,
+ Integer64,
+ IpAddress,
+ Ipv4Address,
+ Ipv6Address,
+ Line,
+ Ltree,
+ MultiLine,
+ MultiPoint,
+ MultiPolygon,
+ Point,
+ Polygon,
+ SimpleModel,
+ String,
+ Time,
+ Unicode,
+ UnsignedInteger,
+ UnsignedInteger8,
+ UnsignedInteger16,
+ UnsignedInteger32,
+ UnsignedInteger64,
+ Uuid,
+)
from spyne.model import json as c_json
from spyne.model import jsonb as c_jsonb
-from spyne.model import table as c_table
from spyne.model import msgpack as c_msgpack
+from spyne.model import table as c_table
+from spyne.model import xml as c_xml
from spyne.model.binary import HybridFileStore
+from spyne.model.complex import XmlModifier
-# public types
-from spyne.model import SimpleModel, Enum, Array, ComplexModelBase, \
- Any, AnyDict, AnyXml, AnyHtml, \
- Date, Time, DateTime, Duration, \
- ByteArray, String, Unicode, Uuid, Boolean, \
- Point, Line, Polygon, MultiPoint, MultiLine, MultiPolygon, \
- Float, Double, Decimal, \
- Integer, Integer8, Integer16, Integer32, Integer64, \
- UnsignedInteger, UnsignedInteger8, UnsignedInteger16, UnsignedInteger32, \
- UnsignedInteger64, \
- Ipv6Address, Ipv4Address, IpAddress, \
- File, Ltree
-
+# internal types
+from spyne.model.enum import EnumBase
+from spyne.store.relational.document import (
+ PGFileJson,
+ PGHtml,
+ PGJson,
+ PGJsonB,
+ PGObjectJson,
+ PGObjectXml,
+ PGXml,
+)
+from spyne.store.relational.simple import PGLTree
+from spyne.store.relational.spatial import PGGeometry
from spyne.util import sanitize_args
@@ -92,6 +118,7 @@
class _SINGLE:
pass
+
class _JOINED:
pass
@@ -101,44 +128,33 @@ class _JOINED:
# distinguish between floats and doubles.
sqlalchemy.Float: Double,
sqlalchemy.FLOAT: Double,
-
sqlalchemy.Numeric: Decimal,
sqlalchemy.NUMERIC: Decimal,
-
sqlalchemy.BigInteger: Integer64,
sqlalchemy.BIGINT: Integer64,
-
sqlalchemy.Integer: Integer32,
sqlalchemy.INTEGER: Integer32,
-
sqlalchemy.SmallInteger: Integer16,
sqlalchemy.SMALLINT: Integer16,
-
sqlalchemy.LargeBinary: ByteArray,
-
sqlalchemy.Boolean: Boolean,
sqlalchemy.BOOLEAN: Boolean,
-
sqlalchemy.DateTime: DateTime,
sqlalchemy.TIMESTAMP: DateTime,
sqlalchemy.dialects.postgresql.base.TIMESTAMP: DateTime,
sqlalchemy.DATETIME: DateTime,
sqlalchemy.dialects.postgresql.base.INTERVAL: Duration,
-
sqlalchemy.Date: Date,
sqlalchemy.DATE: Date,
-
sqlalchemy.Time: Time,
sqlalchemy.TIME: Time,
-
PGUuid: Uuid,
PGLTree: Ltree,
PGInet: IpAddress,
}
-sqlalchemy_BINARY = \
- getattr(sqlalchemy, 'Binary', getattr(sqlalchemy, 'BINARY', None))
+sqlalchemy_BINARY = getattr(sqlalchemy, "Binary", getattr(sqlalchemy, "BINARY", None))
if sqlalchemy_BINARY is not None:
_sq2sp_type_map[sqlalchemy_BINARY] = ByteArray
@@ -149,13 +165,13 @@ def _sp_attrs_to_sqla_constraints(cls, subcls, col_kwargs=None, col=None):
# cls is the parent class of v
if subcls.Attributes.nullable == False and cls.__extends__ is None:
if col is None:
- col_kwargs['nullable'] = False
+ col_kwargs["nullable"] = False
else:
col.nullable = False
if subcls.Attributes.db_default is not None:
if col is None:
- col_kwargs['default'] = subcls.Attributes.db_default
+ col_kwargs["default"] = subcls.Attributes.db_default
else:
col.default = subcls.Attributes.db_default
@@ -203,13 +219,17 @@ def _get_sqlalchemy_type(cls):
# must be above Unicode, because String is Unicode's subclass
if issubclass(cls, String):
- if cls.Attributes.max_len == String.Attributes.max_len: # Default is arbitrary-length
+ if (
+ cls.Attributes.max_len == String.Attributes.max_len
+ ): # Default is arbitrary-length
return sqlalchemy.Text
else:
return sqlalchemy.String(cls.Attributes.max_len)
if issubclass(cls, Unicode):
- if cls.Attributes.max_len == Unicode.Attributes.max_len: # Default is arbitrary-length
+ if (
+ cls.Attributes.max_len == Unicode.Attributes.max_len
+ ): # Default is arbitrary-length
return sqlalchemy.UnicodeText
else:
return sqlalchemy.Unicode(cls.Attributes.max_len)
@@ -266,8 +286,9 @@ def _get_sqlalchemy_type(cls):
if cls.Attributes.store_as is int:
return sqlalchemy.SmallInteger
- raise ValueError("Boolean.store_as has invalid value %r" %
- cls.Attributes.store_as)
+ raise ValueError(
+ "Boolean.store_as has invalid value %r" % cls.Attributes.store_as
+ )
if issubclass(cls, Date):
return sqlalchemy.Date
@@ -292,50 +313,61 @@ def _get_sqlalchemy_type(cls):
return retval
-def _get_col_o2o(parent, subname, subcls, fk_col_name, deferrable=None,
- initially=None, ondelete=None, onupdate=None):
+def _get_col_o2o(
+ parent,
+ subname,
+ subcls,
+ fk_col_name,
+ deferrable=None,
+ initially=None,
+ ondelete=None,
+ onupdate=None,
+):
"""Gets key and child type and returns a column that points to the primary
key of the child.
"""
- assert subcls.Attributes.table_name is not None, \
- "%r has no table name." % subcls
+ assert subcls.Attributes.table_name is not None, "%r has no table name." % subcls
col_args, col_kwargs = sanitize_args(subcls.Attributes.sqla_column_args)
_sp_attrs_to_sqla_constraints(parent, subcls, col_kwargs)
# get pkeys from child class
- pk_column, = get_pk_columns(subcls) # FIXME: Support multi-col keys
+ (pk_column,) = get_pk_columns(subcls) # FIXME: Support multi-col keys
pk_key, pk_spyne_type = pk_column
pk_sqla_type = _get_sqlalchemy_type(pk_spyne_type)
# generate a fk to it from the current object (cls)
- if 'name' in col_kwargs:
- colname = col_kwargs.pop('name')
+ if "name" in col_kwargs:
+ colname = col_kwargs.pop("name")
else:
colname = subname
if fk_col_name is None:
fk_col_name = colname + "_" + pk_key
- assert fk_col_name != colname, \
- "The column name for the foreign key must be different from the " \
+ assert fk_col_name != colname, (
+ "The column name for the foreign key must be different from the "
"column name for the object itself."
+ )
fk = ForeignKey(
- '%s.%s' % (subcls.Attributes.table_name, pk_key),
+ "%s.%s" % (subcls.Attributes.table_name, pk_key),
use_alter=True,
- name='%s_%s_fkey' % (subcls.Attributes.table_name, fk_col_name),
- deferrable=deferrable, initially=initially,
- ondelete=ondelete, onupdate=onupdate,
+ name="%s_%s_fkey" % (subcls.Attributes.table_name, fk_col_name),
+ deferrable=deferrable,
+ initially=initially,
+ ondelete=ondelete,
+ onupdate=onupdate,
)
return Column(fk_col_name, pk_sqla_type, fk, **col_kwargs)
-def _get_col_o2m(cls, fk_col_name, deferrable=None, initially=None,
- ondelete=None, onupdate=None):
+def _get_col_o2m(
+ cls, fk_col_name, deferrable=None, initially=None, ondelete=None, onupdate=None
+):
"""Gets the parent class and returns a column that points to the primary key
of the parent.
"""
@@ -344,42 +376,68 @@ def _get_col_o2m(cls, fk_col_name, deferrable=None, initially=None,
col_args, col_kwargs = sanitize_args(cls.Attributes.sqla_column_args)
# get pkeys from current class
- pk_column, = get_pk_columns(cls) # FIXME: Support multi-col keys
+ (pk_column,) = get_pk_columns(cls) # FIXME: Support multi-col keys
pk_key, pk_spyne_type = pk_column
pk_sqla_type = _get_sqlalchemy_type(pk_spyne_type)
# generate a fk from child to the current class
if fk_col_name is None:
- fk_col_name = '_'.join([cls.Attributes.table_name, pk_key])
+ fk_col_name = "_".join([cls.Attributes.table_name, pk_key])
# we jump through all these hoops because we must instantiate the Column
# only after we're sure that it doesn't already exist and also because
# tinkering with functors is always fun :)
yield [(fk_col_name, pk_sqla_type)]
- fk = ForeignKey('%s.%s' % (cls.Attributes.table_name, pk_key),
- deferrable=deferrable, initially=initially,
- ondelete=ondelete, onupdate=onupdate)
+ fk = ForeignKey(
+ "%s.%s" % (cls.Attributes.table_name, pk_key),
+ deferrable=deferrable,
+ initially=initially,
+ ondelete=ondelete,
+ onupdate=onupdate,
+ )
col = Column(fk_col_name, pk_sqla_type, fk, **col_kwargs)
yield col
-def _get_cols_m2m(cls, k, child, fk_left_col_name, fk_right_col_name,
- fk_left_deferrable, fk_left_initially,
- fk_right_deferrable, fk_right_initially,
- fk_left_ondelete, fk_left_onupdate,
- fk_right_ondelete, fk_right_onupdate):
+def _get_cols_m2m(
+ cls,
+ k,
+ child,
+ fk_left_col_name,
+ fk_right_col_name,
+ fk_left_deferrable,
+ fk_left_initially,
+ fk_right_deferrable,
+ fk_right_initially,
+ fk_left_ondelete,
+ fk_left_onupdate,
+ fk_right_ondelete,
+ fk_right_onupdate,
+):
"""Gets the parent and child classes and returns foreign keys to both
tables. These columns can be used to create a relation table."""
- col_info, left_col = _get_col_o2m(cls, fk_left_col_name,
- ondelete=fk_left_ondelete, onupdate=fk_left_onupdate,
- deferrable=fk_left_deferrable, initially=fk_left_initially)
- right_col = _get_col_o2o(cls, k, child, fk_right_col_name,
- ondelete=fk_right_ondelete, onupdate=fk_right_onupdate,
- deferrable=fk_right_deferrable, initially=fk_right_initially)
+ col_info, left_col = _get_col_o2m(
+ cls,
+ fk_left_col_name,
+ ondelete=fk_left_ondelete,
+ onupdate=fk_left_onupdate,
+ deferrable=fk_left_deferrable,
+ initially=fk_left_initially,
+ )
+ right_col = _get_col_o2o(
+ cls,
+ k,
+ child,
+ fk_right_col_name,
+ ondelete=fk_right_ondelete,
+ onupdate=fk_right_onupdate,
+ deferrable=fk_right_deferrable,
+ initially=fk_right_initially,
+ )
left_col.primary_key = right_col.primary_key = True
return left_col, right_col
@@ -413,7 +471,7 @@ def _gen_index_info(table, col, k, v):
index_name, index_method = index
except (TypeError, ValueError):
- index_name = "%s_%s%s" % (table.name, k, '_unique' if unique else '')
+ index_name = "%s_%s%s" % (table.name, k, "_unique" if unique else "")
index_method = index
if index in (False, None):
@@ -422,8 +480,9 @@ def _gen_index_info(table, col, k, v):
if index is True:
index_args = (index_name, col), dict(unique=unique)
else:
- index_args = (index_name, col), dict(unique=unique,
- postgresql_using=index_method)
+ index_args = (index_name, col), dict(
+ unique=unique, postgresql_using=index_method
+ )
if isinstance(table, _FakeTable):
table.indexes.append(index_args)
@@ -435,27 +494,31 @@ def _gen_index_info(table, col, k, v):
Index(*index_args[0], **index_args[1])
else:
- assert existing_idx.unique == unique, \
- "Uniqueness flag differ between existing and current values. " \
+ assert existing_idx.unique == unique, (
+ "Uniqueness flag differ between existing and current values. "
"Existing: {!r}, New: {!r}".format(existing_idx.unique, unique)
+ )
- existing_val = existing_idx.kwargs.get('postgresql_using')
+ existing_val = existing_idx.kwargs.get("postgresql_using")
- assert existing_val == index_method, \
- "Indexing methods differ between existing and current index " \
+ assert existing_val == index_method, (
+ "Indexing methods differ between existing and current index "
"directives. Existing: {!r}, New: {!r}".format(
- existing_val, index_method)
+ existing_val, index_method
+ )
+ )
+
def _check_inheritance(cls, cls_bases):
table_name = cls.Attributes.table_name
inc = []
inheritance = None
- base_class = getattr(cls, '__extends__', None)
+ base_class = getattr(cls, "__extends__", None)
if base_class is None:
for b in cls_bases:
- if getattr(b, '_type_info', None) is not None and b.__mixin__:
+ if getattr(b, "_type_info", None) is not None and b.__mixin__:
base_class = b
if base_class is not None:
@@ -465,8 +528,9 @@ def _check_inheritance(cls, cls_bases):
inheritance = _SINGLE
else:
inheritance = _JOINED
- raise NotImplementedError("Joined table inheritance is not yet "
- "implemented.")
+ raise NotImplementedError(
+ "Joined table inheritance is not yet " "implemented."
+ )
# check whether the base classes are already mapped
base_mapper = None
@@ -475,7 +539,10 @@ def _check_inheritance(cls, cls_bases):
if base_mapper is None:
for b in cls_bases:
- bm = _mapper_registries.get(b, None)
+ try:
+ bm = sa_inspect(b).mapper
+ except (NoInspectionAvailable, Exception):
+ bm = None
if bm is not None:
assert base_mapper is None, "There can be only one base mapper."
base_mapper = bm
@@ -505,10 +572,10 @@ def _add_simple_type(cls, props, table, subname, subcls, sqla_type):
col_args, col_kwargs = sanitize_args(subcls.Attributes.sqla_column_args)
_sp_attrs_to_sqla_constraints(cls, subcls, col_kwargs)
- mp = getattr(subcls.Attributes, 'mapper_property', None)
+ mp = getattr(subcls.Attributes, "mapper_property", None)
- if 'name' in col_kwargs:
- colname = col_kwargs.pop('name')
+ if "name" in col_kwargs:
+ colname = col_kwargs.pop("name")
else:
colname = subname
@@ -542,12 +609,21 @@ def _gen_array_m2m(cls, props, subname, arrser, storage):
metadata = cls.Attributes.sqla_metadata
- col_own, col_child = _get_cols_m2m(cls, subname, arrser,
- storage.left, storage.right,
- storage.fk_left_deferrable, storage.fk_left_initially,
- storage.fk_right_deferrable, storage.fk_right_initially,
- storage.fk_left_ondelete, storage.fk_left_onupdate,
- storage.fk_right_ondelete, storage.fk_right_onupdate)
+ col_own, col_child = _get_cols_m2m(
+ cls,
+ subname,
+ arrser,
+ storage.left,
+ storage.right,
+ storage.fk_left_deferrable,
+ storage.fk_left_initially,
+ storage.fk_right_deferrable,
+ storage.fk_right_initially,
+ storage.fk_left_ondelete,
+ storage.fk_left_onupdate,
+ storage.fk_right_ondelete,
+ storage.fk_right_onupdate,
+ )
storage.left = col_own.key
storage.right = col_child.key
@@ -555,7 +631,7 @@ def _gen_array_m2m(cls, props, subname, arrser, storage):
# noinspection PySimplifyBooleanCheck because literal True means
# "generate table name automatically" here
if storage.multi is True:
- rel_table_name = '_'.join([cls.Attributes.table_name, subname])
+ rel_table_name = "_".join([cls.Attributes.table_name, subname])
else:
rel_table_name = storage.multi
@@ -582,10 +658,11 @@ def _gen_array_m2m(cls, props, subname, arrser, storage):
rel_kwargs = dict(
lazy=storage.lazy,
backref=storage.backref,
- cascade=storage.cascade,
- order_by=storage.order_by,
+ order_by=storage.order_by or None,
back_populates=storage.back_populates,
)
+ if storage.cascade is not False:
+ rel_kwargs["cascade"] = storage.cascade
if storage.explicit_join:
# Specify primaryjoin and secondaryjoin when requested.
@@ -596,27 +673,31 @@ def _gen_array_m2m(cls, props, subname, arrser, storage):
assert own_t is not None and len(get_pk_columns(cls)) > 0
# FIXME: support more than one pk
- (col_pk_key, _), = get_pk_columns(cls)
+ ((col_pk_key, _),) = get_pk_columns(cls)
col_pk = own_t.c[col_pk_key]
- rel_kwargs.update(dict(
- secondary=rel_t,
- primaryjoin=(col_pk == rel_t.c[col_own.key]),
- secondaryjoin=(col_pk == rel_t.c[col_child.key]),
- ))
+ rel_kwargs.update(
+ dict(
+ secondary=rel_t,
+ primaryjoin=(col_pk == rel_t.c[col_own.key]),
+ secondaryjoin=(col_pk == rel_t.c[col_child.key]),
+ )
+ )
if storage.single_parent is not None:
- rel_kwargs['single_parent'] = storage.single_parent
+ rel_kwargs["single_parent"] = storage.single_parent
props[subname] = relationship(arrser, **rel_kwargs)
else:
- rel_kwargs.update(dict(
- secondary=rel_t,
- ))
+ rel_kwargs.update(
+ dict(
+ secondary=rel_t,
+ )
+ )
if storage.single_parent is not None:
- rel_kwargs['single_parent'] = storage.single_parent
+ rel_kwargs["single_parent"] = storage.single_parent
props[subname] = relationship(arrser, **rel_kwargs)
@@ -636,12 +717,16 @@ def _gen_array_simple(cls, props, subname, arrser_cust, storage):
metadata = cls.Attributes.sqla_metadata
# get left (fk) column info
- _gen_col = _get_col_o2m(cls, storage.left,
- ondelete=storage.fk_left_ondelete, onupdate=storage.fk_left_onupdate,
+ _gen_col = _get_col_o2m(
+ cls,
+ storage.left,
+ ondelete=storage.fk_left_ondelete,
+ onupdate=storage.fk_left_onupdate,
deferrable=storage.fk_left_deferrable,
- initially=storage.fk_left_initially)
+ initially=storage.fk_left_initially,
+ )
- col_info = next(_gen_col) # gets the column name
+ col_info = next(_gen_col) # gets the column name
# FIXME: Add support for multi-column primary keys.
storage.left, child_left_col_type = col_info[0]
child_left_col_name = storage.left
@@ -655,22 +740,29 @@ def _gen_array_simple(cls, props, subname, arrser_cust, storage):
# get table name
child_table_name = arrser_cust.Attributes.table_name
if child_table_name is None:
- child_table_name = '_'.join([table_name, subname])
+ child_table_name = "_".join([table_name, subname])
if child_table_name in metadata.tables:
child_t = metadata.tables[child_table_name]
# if we have the table, make sure have the right column (data column)
- assert child_right_col_type.__class__ is \
- child_t.c[child_right_col_name].type.__class__, "%s.%s: %r != %r" % \
- (cls, child_right_col_name, child_right_col_type.__class__,
- child_t.c[child_right_col_name].type.__class__)
+ assert (
+ child_right_col_type.__class__
+ is child_t.c[child_right_col_name].type.__class__
+ ), "%s.%s: %r != %r" % (
+ cls,
+ child_right_col_name,
+ child_right_col_type.__class__,
+ child_t.c[child_right_col_name].type.__class__,
+ )
if child_left_col_name in child_t.c:
- assert child_left_col_type is \
- child_t.c[child_left_col_name].type.__class__, "%r != %r" % \
- (child_left_col_type,
- child_t.c[child_left_col_name].type.__class__)
+ assert (
+ child_left_col_type is child_t.c[child_left_col_name].type.__class__
+ ), "%r != %r" % (
+ child_left_col_type,
+ child_t.c[child_left_col_name].type.__class__,
+ )
else:
# Table exists but our own foreign key doesn't.
child_left_col = next(_gen_col)
@@ -685,53 +777,62 @@ def _gen_array_simple(cls, props, subname, arrser_cust, storage):
child_left_col = next(_gen_col)
_sp_attrs_to_sqla_constraints(cls, arrser_cust, col=child_left_col)
- child_t = Table(child_table_name , metadata,
- Column('id', sqlalchemy.Integer, primary_key=True),
+ child_t = Table(
+ child_table_name,
+ metadata,
+ Column("id", sqlalchemy.Integer, primary_key=True),
child_left_col,
child_right_col,
)
- _gen_index_info(child_t, child_right_col, child_right_col_name,
- arrser_cust)
+ _gen_index_info(child_t, child_right_col, child_right_col_name, arrser_cust)
# generate temporary class for association proxy
- cls_name = ''.join(x.capitalize() or '_' for x in
- child_table_name.split('_'))
- # generates camelcase class name.
+ cls_name = "".join(x.capitalize() or "_" for x in child_table_name.split("_"))
+ # generates camelcase class name.
def _i(self, *args):
setattr(self, child_right_col_name, args[0])
- cls_ = type("_" + cls_name, (object,), {'__init__': _i})
- mapper(cls_, child_t)
+ cls_ = type("_" + cls_name, (object,), {"__init__": _i})
+ _mapper_registry.map_imperatively(cls_, child_t)
props["_" + subname] = relationship(cls_)
# generate association proxy
- setattr(cls, subname,
- association_proxy("_" + subname, child_right_col_name))
+ setattr(cls, subname, association_proxy("_" + subname, child_right_col_name))
def _gen_array_o2m(cls, props, subname, arrser, arrser_cust, storage):
- _gen_col = _get_col_o2m(cls, storage.right,
- ondelete=storage.fk_right_ondelete, onupdate=storage.fk_right_onupdate,
+ _gen_col = _get_col_o2m(
+ cls,
+ storage.right,
+ ondelete=storage.fk_right_ondelete,
+ onupdate=storage.fk_right_onupdate,
deferrable=storage.fk_right_deferrable,
- initially=storage.fk_right_initially)
+ initially=storage.fk_right_initially,
+ )
col_info = next(_gen_col) # gets the column name
- storage.right, col_type = col_info[0] # FIXME: Add support for multi-column primary keys.
+ storage.right, col_type = col_info[
+ 0
+ ] # FIXME: Add support for multi-column primary keys.
- assert storage.left is None, \
- "'left' is ignored in one-to-many relationships " \
- "with complex types (because they already have a " \
+ assert storage.left is None, (
+ "'left' is ignored in one-to-many relationships "
+ "with complex types (because they already have a "
"table). You probably meant to use 'right'."
+ )
child_t = arrser.__table__
if storage.right in child_t.c:
# TODO: This branch MUST be tested.
new_col_type = child_t.c[storage.right].type.__class__
- assert col_type is child_t.c[storage.right].type.__class__, \
- "Existing column type %r disagrees with new column type %r" % \
- (col_type, new_col_type)
+ assert (
+ col_type is child_t.c[storage.right].type.__class__
+ ), "Existing column type %r disagrees with new column type %r" % (
+ col_type,
+ new_col_type,
+ )
# if the column is already there, the decision about whether
# it should be in child's mapper or not should also have been
@@ -749,18 +850,18 @@ def _gen_array_o2m(cls, props, subname, arrser, arrser_cust, storage):
child_t.append_column(col)
arrser.__mapper__.add_property(col.name, col)
-
rel_kwargs = dict(
lazy=storage.lazy,
backref=storage.backref,
- cascade=storage.cascade,
- order_by=storage.order_by,
+ order_by=storage.order_by or None,
foreign_keys=[col],
back_populates=storage.back_populates,
)
+ if storage.cascade is not False:
+ rel_kwargs["cascade"] = storage.cascade
if storage.single_parent is not None:
- rel_kwargs['single_parent'] = storage.single_parent
+ rel_kwargs["single_parent"] = storage.single_parent
props[subname] = relationship(arrser, **rel_kwargs)
@@ -772,7 +873,7 @@ def _is_array(v):
def _add_array_to_complex(cls, props, subname, subcls, storage):
arrser_cust = subcls
if issubclass(subcls, Array):
- arrser_cust, = subcls._type_info.values()
+ (arrser_cust,) = subcls._type_info.values()
arrser = arrser_cust
if arrser_cust.__orig__ is not None:
@@ -788,8 +889,9 @@ def _add_array_to_complex(cls, props, subname, subcls, storage):
_gen_array_o2m(cls, props, subname, arrser, arrser_cust, storage)
-def _add_simple_type_to_complex(cls, props, table, subname, subcls, storage,
- col_kwargs):
+def _add_simple_type_to_complex(
+ cls, props, table, subname, subcls, storage, col_kwargs
+):
# v has the Attribute values we need whereas real_v is what the
# user instantiates (thus what sqlalchemy needs)
if subcls.__orig__ is None: # vanilla class
@@ -797,22 +899,28 @@ def _add_simple_type_to_complex(cls, props, table, subname, subcls, storage,
else: # customized class
real_v = subcls.__orig__
- assert not getattr(storage, 'multi', False), \
- 'Storing a single element-type using a relation table is pointless.'
+ assert not getattr(
+ storage, "multi", False
+ ), "Storing a single element-type using a relation table is pointless."
- assert storage.right is None, \
- "'right' is ignored in a one-to-one relationship"
+ assert storage.right is None, "'right' is ignored in a one-to-one relationship"
- col = _get_col_o2o(cls, subname, subcls, storage.left,
- ondelete=storage.fk_left_ondelete, onupdate=storage.fk_left_onupdate,
+ col = _get_col_o2o(
+ cls,
+ subname,
+ subcls,
+ storage.left,
+ ondelete=storage.fk_left_ondelete,
+ onupdate=storage.fk_left_onupdate,
deferrable=storage.fk_left_deferrable,
- initially=storage.fk_left_initially)
+ initially=storage.fk_left_initially,
+ )
storage.left = col.name
if col.name in table.c:
col = table.c[col.name]
- if col_kwargs.get('nullable') is False:
+ if col_kwargs.get("nullable") is False:
col.nullable = False
else:
table.append_column(col)
@@ -820,19 +928,18 @@ def _add_simple_type_to_complex(cls, props, table, subname, subcls, storage,
rel_kwargs = dict(
lazy=storage.lazy,
backref=storage.backref,
- order_by=storage.order_by,
+ order_by=storage.order_by or None,
back_populates=storage.back_populates,
)
if storage.single_parent is not None:
- rel_kwargs['single_parent'] = storage.single_parent
+ rel_kwargs["single_parent"] = storage.single_parent
if real_v is (cls.__orig__ or cls):
- (pk_col_name, pk_col_type), = get_pk_columns(cls)
- rel_kwargs['remote_side'] = [table.c[pk_col_name]]
+ ((pk_col_name, pk_col_type),) = get_pk_columns(cls)
+ rel_kwargs["remote_side"] = [table.c[pk_col_name]]
- rel = relationship(real_v, uselist=False, foreign_keys=[col],
- **rel_kwargs)
+ rel = relationship(real_v, uselist=False, foreign_keys=[col], **rel_kwargs)
_gen_index_info(table, col, subname, subcls)
@@ -840,30 +947,32 @@ def _add_simple_type_to_complex(cls, props, table, subname, subcls, storage,
props[col.name] = col
-def _add_complex_type_as_table(cls, props, table, subname, subcls, storage,
- col_args, col_kwargs):
+def _add_complex_type_as_table(
+ cls, props, table, subname, subcls, storage, col_args, col_kwargs
+):
# add one to many relation
if _is_array(subcls):
_add_array_to_complex(cls, props, subname, subcls, storage)
# add one to one relation
else:
- _add_simple_type_to_complex(cls, props, table, subname, subcls,
- storage, col_kwargs)
+ _add_simple_type_to_complex(
+ cls, props, table, subname, subcls, storage, col_kwargs
+ )
-def _add_complex_type_as_xml(cls, props, table, subname, subcls, storage,
- col_args, col_kwargs):
- if 'name' in col_kwargs:
- colname = col_kwargs.pop('name')
+def _add_complex_type_as_xml(
+ cls, props, table, subname, subcls, storage, col_args, col_kwargs
+):
+ if "name" in col_kwargs:
+ colname = col_kwargs.pop("name")
else:
colname = subname
if colname in table.c:
col = table.c[colname]
else:
- t = PGObjectXml(subcls, storage.root_tag, storage.no_ns,
- storage.pretty_print)
+ t = PGObjectXml(subcls, storage.root_tag, storage.no_ns, storage.pretty_print)
col = Column(colname, t, **col_kwargs)
props[subname] = col
@@ -871,10 +980,11 @@ def _add_complex_type_as_xml(cls, props, table, subname, subcls, storage,
table.append_column(col)
-def _add_complex_type_as_json(cls, props, table, subname, subcls, storage,
- col_args, col_kwargs, dbt):
- if 'name' in col_kwargs:
- colname = col_kwargs.pop('name')
+def _add_complex_type_as_json(
+ cls, props, table, subname, subcls, storage, col_args, col_kwargs, dbt
+):
+ if "name" in col_kwargs:
+ colname = col_kwargs.pop("name")
else:
colname = subname
@@ -882,8 +992,12 @@ def _add_complex_type_as_json(cls, props, table, subname, subcls, storage,
col = table.c[colname]
else:
- t = PGObjectJson(subcls, ignore_wrappers=storage.ignore_wrappers,
- complex_as=storage.complex_as, dbt=dbt)
+ t = PGObjectJson(
+ subcls,
+ ignore_wrappers=storage.ignore_wrappers,
+ complex_as=storage.complex_as,
+ dbt=dbt,
+ )
col = Column(colname, t, **col_kwargs)
props[subname] = col
@@ -895,22 +1009,26 @@ def _add_complex_type(cls, props, table, subname, subcls):
if issubclass(subcls, File):
return _add_file_type(cls, props, table, subname, subcls)
- storage = getattr(subcls.Attributes, 'store_as', None)
+ storage = getattr(subcls.Attributes, "store_as", None)
col_args, col_kwargs = sanitize_args(subcls.Attributes.sqla_column_args)
_sp_attrs_to_sqla_constraints(cls, subcls, col_kwargs)
if isinstance(storage, c_table):
- return _add_complex_type_as_table(cls, props, table, subname, subcls,
- storage, col_args, col_kwargs)
+ return _add_complex_type_as_table(
+ cls, props, table, subname, subcls, storage, col_args, col_kwargs
+ )
if isinstance(storage, c_xml):
- return _add_complex_type_as_xml(cls, props, table, subname, subcls,
- storage, col_args, col_kwargs)
+ return _add_complex_type_as_xml(
+ cls, props, table, subname, subcls, storage, col_args, col_kwargs
+ )
if isinstance(storage, c_json):
- return _add_complex_type_as_json(cls, props, table, subname, subcls,
- storage, col_args, col_kwargs, 'json')
+ return _add_complex_type_as_json(
+ cls, props, table, subname, subcls, storage, col_args, col_kwargs, "json"
+ )
if isinstance(storage, c_jsonb):
- return _add_complex_type_as_json(cls, props, table, subname, subcls,
- storage, col_args, col_kwargs, 'jsonb')
+ return _add_complex_type_as_json(
+ cls, props, table, subname, subcls, storage, col_args, col_kwargs, "jsonb"
+ )
if isinstance(storage, c_msgpack):
raise NotImplementedError(c_msgpack)
@@ -926,8 +1044,9 @@ def _convert_fake_table(cls, table):
_table = table
table_args, table_kwargs = sanitize_args(cls.Attributes.sqla_table_args)
- table = Table(table_name, metadata,
- *(tuple(table.columns) + table_args), **table_kwargs)
+ table = Table(
+ table_name, metadata, *(tuple(table.columns) + table_args), **table_kwargs
+ )
for index_args, index_kwargs in _table.indexes:
Index(*index_args, **index_kwargs)
@@ -947,29 +1066,28 @@ def _gen_mapper(cls, props, table, cls_bases):
inheritance, base_class, base_mapper, inc = _check_inheritance(cls, cls_bases)
mapper_args, mapper_kwargs = sanitize_args(cls.Attributes.sqla_mapper_args)
- _props = mapper_kwargs.get('properties', None)
+ _props = mapper_kwargs.get("properties", None)
if _props is None:
- mapper_kwargs['properties'] = props
+ mapper_kwargs["properties"] = props
else:
props.update(_props)
- mapper_kwargs['properties'] = props
+ mapper_kwargs["properties"] = props
- po = mapper_kwargs.get('polymorphic_on', None)
+ po = mapper_kwargs.get("polymorphic_on", None)
if po is not None:
if not isinstance(po, Column):
- mapper_kwargs['polymorphic_on'] = table.c[po]
+ mapper_kwargs["polymorphic_on"] = table.c[po]
else:
- logger.warning("Deleted invalid 'polymorphic_on' value %r for %r.",
- po, cls)
- del mapper_kwargs['polymorphic_on']
+ logger.warning("Deleted invalid 'polymorphic_on' value %r for %r.", po, cls)
+ del mapper_kwargs["polymorphic_on"]
if base_mapper is not None:
- mapper_kwargs['inherits'] = base_mapper
+ mapper_kwargs["inherits"] = base_mapper
if inheritance is not _SINGLE:
mapper_args = (table,) + mapper_args
- cls_mapper = mapper(cls, *mapper_args, **mapper_kwargs)
+ cls_mapper = _mapper_registry.map_imperatively(cls, *mapper_args, **mapper_kwargs)
def on_load(target, context):
d = target.__dict__
@@ -981,13 +1099,13 @@ def on_load(target, context):
else:
d[k] = None
- event.listen(cls, 'load', on_load)
+ event.listen(cls, "load", on_load)
return cls_mapper
def _add_file_type(cls, props, table, subname, subcls):
- storage = getattr(subcls.Attributes, 'store_as', None)
+ storage = getattr(subcls.Attributes, "store_as", None)
col_args, col_kwargs = sanitize_args(subcls.Attributes.sqla_column_args)
_sp_attrs_to_sqla_constraints(cls, subcls, col_kwargs)
@@ -997,12 +1115,12 @@ def _add_file_type(cls, props, table, subname, subcls):
else:
assert isabs(storage.store)
- #FIXME: Add support for storage markers from spyne.model.complex
- if storage.db_format == 'json':
+ # FIXME: Add support for storage markers from spyne.model.complex
+ if storage.db_format == "json":
t = PGFileJson(storage.store, storage.type)
- elif storage.db_format == 'jsonb':
- t = PGFileJson(storage.store, storage.type, dbt='jsonb')
+ elif storage.db_format == "jsonb":
+ t = PGFileJson(storage.store, storage.type, dbt="jsonb")
else:
raise NotImplementedError(storage.db_format)
@@ -1048,7 +1166,7 @@ def _parent_mapper_has_property(cls, cls_bases, k):
return False
for b in cls_bases:
- if not hasattr(b, 'Attributes'):
+ if not hasattr(b, "Attributes"):
continue
mapper = b.Attributes.sqla_mapper
@@ -1087,8 +1205,7 @@ def gen_sqla_info(cls, cls_bases=()):
else:
# when no parents, use all fields anyway.
- assert set(cls._type_info.items()) == \
- set(cls.get_flat_type_info(cls).items())
+ assert set(cls._type_info.items()) == set(cls.get_flat_type_info(cls).items())
fields = cls.get_flat_type_info(cls).items()
@@ -1099,11 +1216,12 @@ def gen_sqla_info(cls, cls_bases=()):
t = _get_sqlalchemy_type(v)
if t is None: # complex model
- p = getattr(v.Attributes, 'store_as', None)
+ p = getattr(v.Attributes, "store_as", None)
if p is None:
- logger.debug("Skipping %s.%s.%s: %r, store_as: %r" % (
- cls.get_namespace(),
- cls.get_type_name(), k, v, p))
+ logger.debug(
+ "Skipping %s.%s.%s: %r, store_as: %r"
+ % (cls.get_namespace(), cls.get_type_name(), k, v, p)
+ )
else:
_add_complex_type(cls, mapper_props, table, k, v)
else:
@@ -1126,24 +1244,23 @@ def _get_spyne_type(v):
cust = {}
if v.primary_key:
- cust['primary_key'] = True
+ cust["primary_key"] = True
if not v.nullable:
- cust['nullable'] = False
- cust['min_occurs'] = 1
+ cust["nullable"] = False
+ cust["min_occurs"] = 1
if isinstance(v.type, sqlalchemy.Enum):
if v.type.convert_unicode:
return Unicode(values=v.type.enums, **cust)
else:
- cust['type_name'] = v.type.name
+ cust["type_name"] = v.type.name
return Enum(*v.type.enums, **cust)
if isinstance(v.type, (sqlalchemy.UnicodeText, sqlalchemy.Text)):
return Unicode(**cust)
- if isinstance(v.type, (sqlalchemy.Unicode, sqlalchemy.String,
- sqlalchemy.VARCHAR)):
+ if isinstance(v.type, (sqlalchemy.Unicode, sqlalchemy.String, sqlalchemy.VARCHAR)):
return Unicode(v.type.length, **cust)
if isinstance(v.type, sqlalchemy.Numeric):
@@ -1182,8 +1299,10 @@ def _get_spyne_type(v):
else:
return retval
- raise Exception("Spyne type was not found. Probably _sq2sp_type_map "
- "needs a new entry. %r" % v)
+ raise Exception(
+ "Spyne type was not found. Probably _sq2sp_type_map "
+ "needs a new entry. %r" % v
+ )
def gen_spyne_info(cls):
@@ -1195,10 +1314,12 @@ def gen_spyne_info(cls):
for c in table.c:
_type_info[c.name] = _get_spyne_type(c)
else:
- mapper_kwargs['include_properties'] = _type_info.keys()
+ mapper_kwargs["include_properties"] = _type_info.keys()
# Map the table to the object
- cls_mapper = mapper(cls, table, *mapper_args, **mapper_kwargs)
+ cls_mapper = _mapper_registry.map_imperatively(
+ cls, table, *mapper_args, **mapper_kwargs
+ )
cls.Attributes.table_name = cls.__tablename__ = table.name
cls.Attributes.sqla_mapper = cls.__mapper__ = cls_mapper
@@ -1209,8 +1330,9 @@ def get_pk_columns(cls):
retval = []
for k, v in cls.get_flat_type_info(cls).items():
- if v.Attributes.sqla_column_args is not None and \
- v.Attributes.sqla_column_args[-1].get('primary_key', False):
+ if v.Attributes.sqla_column_args is not None and v.Attributes.sqla_column_args[
+ -1
+ ].get("primary_key", False):
retval.append((k, v))
return tuple(retval) if len(retval) > 0 else None
diff --git a/spyne/store/relational/document.py b/spyne/store/relational/document.py
index 21e49d8ac..f780e1166 100644
--- a/spyne/store/relational/document.py
+++ b/spyne/store/relational/document.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,22 +17,22 @@
#
import logging
+
logger = logging.getLogger(__name__)
-import os
import json
+import os
import shutil
+from contextlib import closing
+from mmap import ACCESS_READ, mmap
+from os.path import abspath, basename, dirname, isfile, join
+from uuid import uuid1
import sqlalchemy.dialects
-from uuid import uuid1
-from mmap import mmap, ACCESS_READ
-from contextlib import closing
-from os.path import join, abspath, dirname, basename, isfile
-
try:
- from lxml import etree
- from lxml import html
+ from lxml import etree, html
+
from spyne.util.xml import get_object_as_xml, get_xml_as_object
except ImportError as _import_error:
@@ -41,24 +40,25 @@
html = None
_local_import_error = _import_error
+
def get_object_as_xml(*_, **__):
raise _local_import_error
+
def get_xml_as_object(*_, **__):
raise _local_import_error
+
+from io import BytesIO, StringIO
+
from sqlalchemy.sql.type_api import UserDefinedType
from spyne import ValidationError
from spyne.model.relational import FileData
-
-from spyne.util import six
-from spyne.util.six import binary_type, text_type, BytesIO, StringIO
from spyne.util.fileproxy import SeekableFileProxy
class PGXml(UserDefinedType):
- def __init__(self, pretty_print=False, xml_declaration=False,
- encoding='UTF-8'):
+ def __init__(self, pretty_print=False, xml_declaration=False, encoding="UTF-8"):
super(PGXml, self).__init__()
self.xml_declaration = xml_declaration
self.pretty_print = pretty_print
@@ -69,16 +69,15 @@ def get_col_spec(self, **_):
def bind_processor(self, dialect):
def process(value):
- if value is None or \
- isinstance(value, (six.text_type, six.binary_type)):
+ if value is None or isinstance(value, (str, bytes)):
return value
- if six.PY2:
- return etree.tostring(value, pretty_print=self.pretty_print,
- encoding=self.encoding, xml_declaration=False)
-
- return etree.tostring(value, pretty_print=self.pretty_print,
- encoding="unicode", xml_declaration=False)
+ return etree.tostring(
+ value,
+ pretty_print=self.pretty_print,
+ encoding="unicode",
+ xml_declaration=False,
+ )
return process
@@ -88,13 +87,15 @@ def process(value):
return etree.fromstring(value)
else:
return value
+
return process
-sqlalchemy.dialects.postgresql.base.ischema_names['xml'] = PGXml
+
+sqlalchemy.dialects.postgresql.base.ischema_names["xml"] = PGXml
class PGHtml(UserDefinedType):
- def __init__(self, pretty_print=False, encoding='UTF-8'):
+ def __init__(self, pretty_print=False, encoding="UTF-8"):
super(PGHtml, self).__init__()
self.pretty_print = pretty_print
@@ -105,12 +106,13 @@ def get_col_spec(self, **_):
def bind_processor(self, dialect):
def process(value):
- if isinstance(value, (six.text_type, six.binary_type)) \
- or value is None:
+ if isinstance(value, (str, bytes)) or value is None:
return value
else:
- return html.tostring(value, pretty_print=self.pretty_print,
- encoding=self.encoding)
+ return html.tostring(
+ value, pretty_print=self.pretty_print, encoding=self.encoding
+ )
+
return process
def result_processor(self, dialect, col_type):
@@ -119,11 +121,12 @@ def process(value):
return html.fromstring(value)
else:
return None
+
return process
class PGJson(UserDefinedType):
- def __init__(self, encoding='UTF-8'):
+ def __init__(self, encoding="UTF-8"):
self.encoding = encoding
def get_col_spec(self, **_):
@@ -131,24 +134,24 @@ def get_col_spec(self, **_):
def bind_processor(self, dialect):
def process(value):
- if isinstance(value, (text_type, binary_type)) or value is None:
+ if isinstance(value, (str, bytes)) or value is None:
return value
else:
- if six.PY2:
- return json.dumps(value, encoding=self.encoding)
- else:
- return json.dumps(value)
+ return json.dumps(value)
+
return process
def result_processor(self, dialect, col_type):
def process(value):
- if isinstance(value, (text_type, binary_type)):
+ if isinstance(value, (str, bytes)):
return json.loads(value)
else:
return value
+
return process
-sqlalchemy.dialects.postgresql.base.ischema_names['json'] = PGJson
+
+sqlalchemy.dialects.postgresql.base.ischema_names["json"] = PGJson
class PGJsonB(PGJson):
@@ -156,12 +159,11 @@ def get_col_spec(self, **_):
return "jsonb"
-sqlalchemy.dialects.postgresql.base.ischema_names['jsonb'] = PGJsonB
+sqlalchemy.dialects.postgresql.base.ischema_names["jsonb"] = PGJsonB
class PGObjectXml(UserDefinedType):
- def __init__(self, cls, root_tag_name=None, no_namespace=False,
- pretty_print=False):
+ def __init__(self, cls, root_tag_name=None, no_namespace=False, pretty_print=False):
self.cls = cls
self.root_tag_name = root_tag_name
self.no_namespace = no_namespace
@@ -173,29 +175,37 @@ def get_col_spec(self, **_):
def bind_processor(self, dialect):
def process(value):
if value is not None:
- return etree.tostring(get_object_as_xml(value, self.cls,
- self.root_tag_name, self.no_namespace), encoding='utf8',
- pretty_print=self.pretty_print, xml_declaration=False)
+ return etree.tostring(
+ get_object_as_xml(
+ value, self.cls, self.root_tag_name, self.no_namespace
+ ),
+ encoding="utf8",
+ pretty_print=self.pretty_print,
+ xml_declaration=False,
+ )
+
return process
def result_processor(self, dialect, col_type):
def process(value):
if value is not None:
return get_xml_as_object(etree.fromstring(value), self.cls)
+
return process
class PGObjectJson(UserDefinedType):
- def __init__(self, cls, ignore_wrappers=True, complex_as=dict, dbt='json',
- encoding='utf8'):
+ def __init__(
+ self, cls, ignore_wrappers=True, complex_as=dict, dbt="json", encoding="utf8"
+ ):
self.cls = cls
self.ignore_wrappers = ignore_wrappers
self.complex_as = complex_as
self.dbt = dbt
self.encoding = encoding
- from spyne.util.dictdoc import get_dict_as_object
- from spyne.util.dictdoc import get_object_as_json
+ from spyne.util.dictdoc import get_dict_as_object, get_object_as_json
+
self.get_object_as_json = get_object_as_json
self.get_dict_as_object = get_dict_as_object
@@ -206,7 +216,9 @@ def bind_processor(self, dialect):
def process(value):
if value is not None:
try:
- return self.get_object_as_json(value, self.cls,
+ return self.get_object_as_json(
+ value,
+ self.cls,
ignore_wrappers=self.ignore_wrappers,
complex_as=self.complex_as,
).decode(self.encoding)
@@ -224,32 +236,37 @@ def process(value):
if value is None:
return None
- if isinstance(value, six.binary_type):
+ if isinstance(value, bytes):
value = value.decode(self.encoding)
- if isinstance(value, six.text_type):
- return self.get_dict_as_object(json.loads(value), self.cls,
- ignore_wrappers=self.ignore_wrappers,
- complex_as=self.complex_as,
- protocol=JsonDocument,
- )
-
- return self.get_dict_as_object(value, self.cls,
+ if isinstance(value, str):
+ return self.get_dict_as_object(
+ json.loads(value),
+ self.cls,
ignore_wrappers=self.ignore_wrappers,
complex_as=self.complex_as,
protocol=JsonDocument,
)
+ return self.get_dict_as_object(
+ value,
+ self.cls,
+ ignore_wrappers=self.ignore_wrappers,
+ complex_as=self.complex_as,
+ protocol=JsonDocument,
+ )
+
return process
class PGFileJson(PGObjectJson):
- def __init__(self, store, type=None, dbt='json'):
+ def __init__(self, store, type=None, dbt="json"):
if type is None:
type = FileData
- super(PGFileJson, self).__init__(type, ignore_wrappers=True,
- complex_as=list, dbt=dbt)
+ super(PGFileJson, self).__init__(
+ type, ignore_wrappers=True, complex_as=list, dbt=dbt
+ )
self.store = store
def bind_processor(self, dialect):
@@ -259,10 +276,12 @@ def process(value):
value.path = uuid1().hex
fp = join(self.store, value.path)
if not abspath(fp).startswith(self.store):
- raise ValidationError(value.path, "Path %r contains "
- "relative path operators (e.g. '..')")
+ raise ValidationError(
+ value.path,
+ "Path %r contains " "relative path operators (e.g. '..')",
+ )
- with open(fp, 'wb') as file:
+ with open(fp, "wb") as file:
for d in value.data:
file.write(d)
@@ -270,16 +289,19 @@ def process(value):
value.path = uuid1().hex
fp = join(self.store, value.path)
if not abspath(fp).startswith(self.store):
- raise ValidationError(value.path, "Path %r contains "
- "relative path operators (e.g. '..')")
+ raise ValidationError(
+ value.path,
+ "Path %r contains " "relative path operators (e.g. '..')",
+ )
if isinstance(value.handle, (StringIO, BytesIO)):
- with open(fp, 'wb') as out_file:
+ with open(fp, "wb") as out_file:
out_file.write(value.handle.getvalue())
else:
- with closing(mmap(value.handle.fileno(), 0,
- access=ACCESS_READ)) as data:
- with open(fp, 'wb') as out_file:
+ with closing(
+ mmap(value.handle.fileno(), 0, access=ACCESS_READ)
+ ) as data:
+ with open(fp, "wb") as out_file:
out_file.write(data)
elif value.path is not None:
@@ -293,25 +315,27 @@ def process(value):
if value.move:
shutil.move(in_file_path, dest)
- logger.debug("move '%s' => '%s'",
- in_file_path, dest)
+ logger.debug("move '%s' => '%s'", in_file_path, dest)
else:
shutil.copy(in_file_path, dest)
- logger.debug("copy '%s' => '%s'",
- in_file_path, dest)
+ logger.debug("copy '%s' => '%s'", in_file_path, dest)
value.path = basename(dest)
value.abspath = dest
else:
- raise ValueError("Invalid file object passed in. All of "
- ".data, .handle and .path are None.")
+ raise ValueError(
+ "Invalid file object passed in. All of "
+ ".data, .handle and .path are None."
+ )
value.store = self.store
value.abspath = join(self.store, value.path)
- return self.get_object_as_json(value, self.cls,
+ return self.get_object_as_json(
+ value,
+ self.cls,
ignore_wrappers=self.ignore_wrappers,
complex_as=self.complex_as,
)
@@ -323,28 +347,32 @@ def process(value):
if value is None:
return None
- if isinstance(value, six.text_type):
+ if isinstance(value, str):
value = json.loads(value)
- elif isinstance(value, six.binary_type):
- value = json.loads(value.decode('utf8'))
+ elif isinstance(value, bytes):
+ value = json.loads(value.decode("utf8"))
- retval = self.get_dict_as_object(value, self.cls,
- ignore_wrappers=self.ignore_wrappers,
- complex_as=self.complex_as)
+ retval = self.get_dict_as_object(
+ value,
+ self.cls,
+ ignore_wrappers=self.ignore_wrappers,
+ complex_as=self.complex_as,
+ )
retval.store = self.store
retval.abspath = path = join(self.store, retval.path)
retval.handle = None
- retval.data = [b'']
+ retval.data = [b""]
if not os.access(path, os.R_OK):
import traceback
+
traceback.print_stack()
logger.error("File '%s' is not readable", path)
return retval
- h = retval.handle = SeekableFileProxy(open(path, 'rb'))
+ h = retval.handle = SeekableFileProxy(open(path, "rb"))
if os.fstat(retval.handle.fileno()).st_size > 0:
h.mmap = mmap(h.fileno(), 0, access=ACCESS_READ)
retval.data = (h.mmap,)
diff --git a/spyne/store/relational/override.py b/spyne/store/relational/override.py
index e04f2fb5c..a4c851f78 100644
--- a/spyne/store/relational/override.py
+++ b/spyne/store/relational/override.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,11 +17,17 @@
#
+from sqlalchemy.dialects.postgresql import INET
from sqlalchemy.ext.compiler import compiles
-from sqlalchemy.dialects.postgresql import INET
-from spyne.store.relational import PGXml, PGJson, PGHtml, PGJsonB, \
- PGObjectJson, PGFileJson
+from spyne.store.relational.document import (
+ PGFileJson,
+ PGHtml,
+ PGJson,
+ PGJsonB,
+ PGObjectJson,
+ PGXml,
+)
@compiles(PGXml)
@@ -60,7 +65,6 @@ def compile_inet(type_, compiler, **kw):
return "inet"
-
@compiles(PGXml, "firebird")
def compile_xml_firebird(type_, compiler, **kw):
return "blob"
diff --git a/spyne/store/relational/simple.py b/spyne/store/relational/simple.py
index 0b2aeba96..828fa4f80 100644
--- a/spyne/store/relational/simple.py
+++ b/spyne/store/relational/simple.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,10 +17,10 @@
#
from sqlalchemy import sql
+from sqlalchemy.dialects.postgresql import ARRAY as PGArray
+from sqlalchemy.dialects.postgresql import UUID as PGUuid
+from sqlalchemy.dialects.postgresql.base import PGTypeCompiler, ischema_names
from sqlalchemy.ext.compiler import compiles
-from sqlalchemy.dialects.postgresql.base import ischema_names, PGTypeCompiler
-from sqlalchemy.dialects.postgresql import ARRAY as PGArray, UUID as PGUuid
-
from sqlalchemy.sql.sqltypes import Concatenable
from sqlalchemy.sql.type_api import UserDefinedType
@@ -31,64 +30,63 @@ def compile_uuid_sqlite(type_, compiler, **kw):
return "BLOB"
-
class PGLTree(Concatenable, UserDefinedType):
"""Postgresql `ltree` type."""
class Comparator(Concatenable.Comparator):
def ancestor_of(self, other):
if isinstance(other, list):
- return self.op('@>')(sql.cast(other, PGArray(PGLTree)))
+ return self.op("@>")(sql.cast(other, PGArray(PGLTree)))
else:
- return self.op('@>')(other)
+ return self.op("@>")(other)
def descendant_of(self, other):
if isinstance(other, list):
- return self.op('<@')(sql.cast(other, PGArray(PGLTree)))
+ return self.op("<@")(sql.cast(other, PGArray(PGLTree)))
else:
- return self.op('<@')(other)
+ return self.op("<@")(other)
def lquery(self, other):
if isinstance(other, list):
- return self.op('?')(sql.cast(other, PGArray(PGLQuery)))
+ return self.op("?")(sql.cast(other, PGArray(PGLQuery)))
else:
- return self.op('~')(other)
+ return self.op("~")(other)
def ltxtquery(self, other):
- return self.op('@')(other)
+ return self.op("@")(other)
comparator_factory = Comparator
- __visit_name__ = 'LTREE'
+ __visit_name__ = "LTREE"
class PGLQuery(UserDefinedType):
"""Postresql `lquery` type."""
- __visit_name__ = 'LQUERY'
+ __visit_name__ = "LQUERY"
class PGLTxtQuery(UserDefinedType):
"""Postresql `ltxtquery` type."""
- __visit_name__ = 'LTXTQUERY'
+ __visit_name__ = "LTXTQUERY"
-ischema_names['ltree'] = PGLTree
-ischema_names['lquery'] = PGLQuery
-ischema_names['ltxtquery'] = PGLTxtQuery
+ischema_names["ltree"] = PGLTree
+ischema_names["lquery"] = PGLQuery
+ischema_names["ltxtquery"] = PGLTxtQuery
def visit_LTREE(self, type_, **kw):
- return 'LTREE'
+ return "LTREE"
def visit_LQUERY(self, type_, **kw):
- return 'LQUERY'
+ return "LQUERY"
def visit_LTXTQUERY(self, type_, **kw):
- return 'LTXTQUERY'
+ return "LTXTQUERY"
PGTypeCompiler.visit_LTREE = visit_LTREE
diff --git a/spyne/store/relational/spatial.py b/spyne/store/relational/spatial.py
index 152362beb..645e7d5b6 100644
--- a/spyne/store/relational/spatial.py
+++ b/spyne/store/relational/spatial.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -31,21 +30,20 @@ class PlainWkt:
class PlainWkb:
pass
- def __init__(self, geometry_type='GEOMETRY', srid=4326, dimension=2,
- format='wkt'):
+ def __init__(self, geometry_type="GEOMETRY", srid=4326, dimension=2, format="wkt"):
self.geometry_type = geometry_type.upper()
- self.name = 'geometry'
+ self.name = "geometry"
self.srid = int(srid)
self.dimension = dimension
self.format = format
- if self.format == 'wkt':
+ if self.format == "wkt":
self.format = PGGeometry.PlainWkt
- elif self.format == 'wkb':
+ elif self.format == "wkb":
self.format = PGGeometry.PlainWkb
def get_col_spec(self):
- return '%s(%s,%d)' % (self.name, self.geometry_type, self.srid)
+ return "%s(%s,%d)" % (self.name, self.geometry_type, self.srid)
def column_expression(self, col):
if self.format is PGGeometry.PlainWkb:
@@ -55,11 +53,13 @@ def column_expression(self, col):
def result_processor(self, dialect, coltype):
if self.format is PGGeometry.PlainWkt:
+
def process(value):
if value is not None:
return value
if self.format is PGGeometry.PlainWkb:
+
def process(value):
if value is not None:
return sql.func.ST_AsBinary(value, self.srid)
@@ -76,7 +76,7 @@ def bind_expression(self, bindvalue):
@compiles(PGGeometry)
def compile_geometry(type_, compiler, **kw):
- return '%s(%s,%d)' % (type_.name, type_.geometry_type, type_.srid)
+ return "%s(%s,%d)" % (type_.name, type_.geometry_type, type_.srid)
@compiles(PGGeometry, "sqlite")
diff --git a/spyne/store/relational/util.py b/spyne/store/relational/util.py
index e30633f32..4ae4f2189 100644
--- a/spyne/store/relational/util.py
+++ b/spyne/store/relational/util.py
@@ -31,9 +31,8 @@
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
-import os
import cProfile
-
+import os
from copy import copy
from sqlalchemy.engine import Dialect, create_engine
@@ -53,7 +52,7 @@ def get_bind(obj):
get_bind(session) # Connection object
get_bind(user)
"""
- if hasattr(obj, 'bind'):
+ if hasattr(obj, "bind"):
conn = obj.bind
else:
try:
@@ -61,10 +60,10 @@ def get_bind(obj):
except UnmappedInstanceError:
conn = obj
- if not hasattr(conn, 'execute'):
+ if not hasattr(conn, "execute"):
raise TypeError(
- 'This method accepts only Session, Engine, Connection and '
- 'declarative model objects.'
+ "This method accepts only Session, Engine, Connection and "
+ "declarative model objects."
)
return conn
@@ -112,27 +111,29 @@ def database_exists(url):
url = copy(make_url(url))
database = url.database
- if url.drivername.startswith('postgres'):
- url.database = 'postgres'
- elif not url.drivername.startswith('sqlite'):
+ if url.drivername.startswith("postgres"):
+ url.database = "postgres"
+ elif not url.drivername.startswith("sqlite"):
url.database = None
engine = create_engine(url)
- if engine.dialect.name == 'postgresql':
+ if engine.dialect.name == "postgresql":
text = "SELECT 1 FROM pg_database WHERE datname='%s'" % database
return bool(engine.execute(text).scalar())
- elif engine.dialect.name == 'mysql':
- text = ("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA "
- "WHERE SCHEMA_NAME = '%s'" % database)
+ elif engine.dialect.name == "mysql":
+ text = (
+ "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA "
+ "WHERE SCHEMA_NAME = '%s'" % database
+ )
return bool(engine.execute(text).scalar())
- elif engine.dialect.name == 'sqlite':
- return database == ':memory:' or os.path.exists(database)
+ elif engine.dialect.name == "sqlite":
+ return database == ":memory:" or os.path.exists(database)
else:
- text = 'SELECT 1'
+ text = "SELECT 1"
try:
url.database = database
engine = create_engine(url)
@@ -143,7 +144,7 @@ def database_exists(url):
return False
-def create_database(url, encoding='utf8', psql_template='template1'):
+def create_database(url, encoding="utf8", psql_template="template1"):
"""Issue the appropriate CREATE DATABASE statement.
:param url: A SQLAlchemy engine URL.
@@ -170,39 +171,35 @@ def create_database(url, encoding='utf8', psql_template='template1'):
database = url.database
- if url.drivername.startswith('postgres'):
- url.database = 'postgres'
- elif not url.drivername.startswith('sqlite'):
+ if url.drivername.startswith("postgres"):
+ url.database = "postgres"
+ elif not url.drivername.startswith("sqlite"):
url.database = None
engine = create_engine(url)
- if engine.dialect.name == 'postgresql':
- if engine.driver == 'psycopg2':
+ if engine.dialect.name == "postgresql":
+ if engine.driver == "psycopg2":
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
- engine.raw_connection().set_isolation_level(
- ISOLATION_LEVEL_AUTOCOMMIT
- )
+
+ engine.raw_connection().set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
text = "CREATE DATABASE {0} ENCODING '{1}' TEMPLATE {2}".format(
- quote(engine, database),
- encoding,
- quote(engine, psql_template)
+ quote(engine, database), encoding, quote(engine, psql_template)
)
engine.execute(text)
- elif engine.dialect.name == 'mysql':
+ elif engine.dialect.name == "mysql":
text = "CREATE DATABASE {0} CHARACTER SET = '{1}'".format(
- quote(engine, database),
- encoding
+ quote(engine, database), encoding
)
engine.execute(text)
- elif engine.dialect.name == 'sqlite' and database != ':memory:':
- open(database, 'w').close()
+ elif engine.dialect.name == "sqlite" and database != ":memory:":
+ open(database, "w").close()
else:
- text = 'CREATE DATABASE {0}'.format(quote(engine, database))
+ text = "CREATE DATABASE {0}".format(quote(engine, database))
engine.execute(text)
@@ -223,44 +220,40 @@ def drop_database(url):
database = url.database
- if url.drivername.startswith('postgresql'):
- url.database = 'template1'
- elif not url.drivername.startswith('sqlite'):
+ if url.drivername.startswith("postgresql"):
+ url.database = "template1"
+ elif not url.drivername.startswith("sqlite"):
url.database = None
engine = create_engine(url)
- if engine.dialect.name == 'sqlite' and url.database != ':memory:':
+ if engine.dialect.name == "sqlite" and url.database != ":memory:":
os.remove(url.database)
- elif engine.dialect.name == 'postgresql' and engine.driver == 'psycopg2':
+ elif engine.dialect.name == "postgresql" and engine.driver == "psycopg2":
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
+
engine.raw_connection().set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
# Disconnect all users from the database we are dropping.
version = list(
- map(
- int,
- engine.execute('SHOW server_version').first()[0].split('.')
- )
- )
- pid_column = (
- 'pid' if (version[0] >= 9 and version[1] >= 2) else 'procpid'
+ map(int, engine.execute("SHOW server_version").first()[0].split("."))
)
- text = '''
+ pid_column = "pid" if (version[0] >= 9 and version[1] >= 2) else "procpid"
+ text = """
SELECT pg_terminate_backend(pg_stat_activity.%(pid_column)s)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = '%(database)s'
AND %(pid_column)s <> pg_backend_pid();
- ''' % {'pid_column': pid_column, 'database': database}
+ """ % {"pid_column": pid_column, "database": database}
engine.execute(text)
# Drop the database.
- text = 'DROP DATABASE {0}'.format(quote(engine, database))
+ text = "DROP DATABASE {0}".format(quote(engine, database))
engine.execute(text)
else:
- text = 'DROP DATABASE {0}'.format(quote(engine, database))
+ text = "DROP DATABASE {0}".format(quote(engine, database))
engine.execute(text)
@@ -274,6 +267,6 @@ def profiled_func(*args, **kwargs):
profile.disable()
return result
finally:
- profile.print_stats(sort='time')
+ profile.print_stats(sort="time")
return profiled_func
diff --git a/spyne/test/__init__.py b/spyne/test/__init__.py
index 51fda37c1..053d288a8 100644
--- a/spyne/test/__init__.py
+++ b/spyne/test/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -17,15 +16,18 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
+
class FakeApp(object):
- transport = 'transport'
- tns = 'tns'
- name = 'name'
+ transport = "transport"
+ tns = "tns"
+ name = "name"
services = []
classes = ()
+
import logging
+
logging.basicConfig(level=logging.DEBUG)
-logging.getLogger('spyne.util.appreg').setLevel(logging.INFO)
+logging.getLogger("spyne.util.appreg").setLevel(logging.INFO)
from spyne.context import FakeContext
diff --git a/spyne/test/conftest.py b/spyne/test/conftest.py
new file mode 100644
index 000000000..cf5541ba3
--- /dev/null
+++ b/spyne/test/conftest.py
@@ -0,0 +1,9 @@
+import pytest
+
+import spyne.util.appreg as appreg
+
+
+@pytest.fixture(autouse=True)
+def clear_app_registry():
+ yield
+ appreg.applications.clear()
diff --git a/spyne/test/interface/test_interface.py b/spyne/test/interface/test_interface.py
index a47c7c5bb..6dfdb0483 100755
--- a/spyne/test/interface/test_interface.py
+++ b/spyne/test/interface/test_interface.py
@@ -21,8 +21,16 @@
import unittest
from spyne import Application, Service, rpc
-from spyne.model import Array, ComplexModel, AnyXml, UnsignedLong, \
- UnsignedInteger16, Integer, DateTime, Unicode
+from spyne.model import (
+ AnyXml,
+ Array,
+ ComplexModel,
+ DateTime,
+ Integer,
+ Unicode,
+ UnsignedInteger16,
+ UnsignedLong,
+)
from spyne.protocol.http import HttpRpc
from spyne.protocol.soap import Soap11
@@ -30,6 +38,7 @@
class TestInterface(unittest.TestCase):
def test_imports(self):
import logging
+
logging.basicConfig(level=logging.DEBUG)
class KeyValuePair(ComplexModel):
@@ -62,10 +71,12 @@ class Service2(Service):
def some_other_call(ctx, sth):
pass
- application = Application([Service1, Service2],
+ application = Application(
+ [Service1, Service2],
in_protocol=HttpRpc(),
out_protocol=Soap11(),
- name='Service', tns='target_namespace'
+ name="Service",
+ tns="target_namespace",
)
imports = application.interface.imports
@@ -73,20 +84,20 @@ def some_other_call(ctx, sth):
smm = application.interface.service_method_map
print(imports)
- assert imports[tns] == set(['1', '3', '4'])
- assert imports['3'] == set(['2'])
- assert imports['4'] == set(['2'])
+ assert imports[tns] == set(["1", "3", "4"])
+ assert imports["3"] == set(["2"])
+ assert imports["4"] == set(["2"])
- assert smm['{%s}some_call' % tns]
- assert smm['{%s}some_call' % tns][0].service_class == Service1
- assert smm['{%s}some_call' % tns][0].function == Service1.some_call
+ assert smm["{%s}some_call" % tns]
+ assert smm["{%s}some_call" % tns][0].service_class == Service1
+ assert smm["{%s}some_call" % tns][0].function == Service1.some_call
- assert smm['{%s}some_other_call' % tns]
- assert smm['{%s}some_other_call' % tns][0].service_class == Service2
- assert smm['{%s}some_other_call' % tns][0].function == Service2.some_other_call
+ assert smm["{%s}some_other_call" % tns]
+ assert smm["{%s}some_other_call" % tns][0].service_class == Service2
+ assert smm["{%s}some_other_call" % tns][0].function == Service2.some_other_call
def test_custom_primitive_in_array(self):
- RequestStatus = Unicode(values=['new', 'processed'], zonta='bonta')
+ RequestStatus = Unicode(values=["new", "processed"], zonta="bonta")
class DataRequest(ComplexModel):
status = Array(RequestStatus)
@@ -96,12 +107,15 @@ class HelloWorldService(Service):
def some_call(ctx, dgrntcl):
pass
- Application([HelloWorldService], 'spyne.examples.hello.soap',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11())
+ Application(
+ [HelloWorldService],
+ "spyne.examples.hello.soap",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
+ )
# test passes if instantiating Application doesn't fail
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/interface/test_wsgi.py b/spyne/test/interface/test_wsgi.py
index e27f3c88c..a7e3799cc 100755
--- a/spyne/test/interface/test_wsgi.py
+++ b/spyne/test/interface/test_wsgi.py
@@ -18,16 +18,14 @@
#
import unittest
+from io import StringIO
-from spyne.util import six
-from spyne.util.six import StringIO
-
-from spyne.protocol.soap.soap11 import Soap11
-from spyne.server.wsgi import WsgiApplication
from spyne.application import Application
-from spyne.model.primitive import Unicode
-from spyne.decorator import rpc
from spyne.const.xml import WSDL11
+from spyne.decorator import rpc
+from spyne.model.primitive import Unicode
+from spyne.protocol.soap.soap11 import Soap11
+from spyne.server.wsgi import WsgiApplication
from spyne.service import Service
@@ -42,9 +40,9 @@ class SomeService(Service):
def some_call(ctx, some_str):
print(some_str)
-
- app = Application([SomeService], "some_tns", in_protocol=Soap11(),
- out_protocol=Soap11())
+ app = Application(
+ [SomeService], "some_tns", in_protocol=Soap11(), out_protocol=Soap11()
+ )
self.wsgi_app = WsgiApplication(app)
def test_document_built(self):
@@ -54,38 +52,46 @@ def on_wsdl_document_built(doc):
self.h += 1
self.wsgi_app.doc.wsdl11.event_manager.add_listener(
- "wsdl_document_built", on_wsdl_document_built)
+ "wsdl_document_built", on_wsdl_document_built
+ )
self.wsgi_app.doc.wsdl11.build_interface_document("http://some_url/")
assert self.h == 1
def test_document_manipulation(self):
def on_wsdl_document_built(doc):
- doc.root_elt.tag = 'ehe'
+ doc.root_elt.tag = "ehe"
self.wsgi_app.doc.wsdl11.event_manager.add_listener(
- "wsdl_document_built", on_wsdl_document_built)
+ "wsdl_document_built", on_wsdl_document_built
+ )
self.wsgi_app.doc.wsdl11.build_interface_document("http://some_url/")
d = self.wsgi_app.doc.wsdl11.get_interface_document()
from lxml import etree
- assert etree.fromstring(d).tag == 'ehe'
+ assert etree.fromstring(d).tag == "ehe"
def test_wsgi(self):
- retval = b''.join(self.wsgi_app({
- 'PATH_INFO': '/',
- 'QUERY_STRING': 'wsdl',
- 'SERVER_NAME': 'localhost',
- 'SERVER_PORT': '7000',
- 'REQUEST_METHOD': 'GET',
- 'wsgi.url_scheme': 'http',
- 'wsgi.input': StringIO(),
- }, start_response))
+ retval = b"".join(
+ self.wsgi_app(
+ {
+ "PATH_INFO": "/",
+ "QUERY_STRING": "wsdl",
+ "SERVER_NAME": "localhost",
+ "SERVER_PORT": "7000",
+ "REQUEST_METHOD": "GET",
+ "wsgi.url_scheme": "http",
+ "wsgi.input": StringIO(),
+ },
+ start_response,
+ )
+ )
from lxml import etree
- assert etree.fromstring(retval).tag == WSDL11('definitions')
+ assert etree.fromstring(retval).tag == WSDL11("definitions")
+
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/interface/test_xml_schema.py b/spyne/test/interface/test_xml_schema.py
index 416353905..ed23e2dd6 100755
--- a/spyne/test/interface/test_xml_schema.py
+++ b/spyne/test/interface/test_xml_schema.py
@@ -19,32 +19,25 @@
import logging
import unittest
-
from pprint import pprint
+
from lxml import etree
-from spyne import Application
-from spyne import rpc
+from spyne import Application, rpc
from spyne.const import xml as ns
from spyne.const.xml import NS_XSD
-from spyne.model import ByteArray
-from spyne.model import ComplexModel
-from spyne.model import XmlAttribute
-from spyne.model import XmlData
-from spyne.model import AnyXml
-from spyne.model import Integer
+from spyne.interface.xml_schema import XmlSchema
+from spyne.interface.xml_schema.genpy import CodeGenerator
+from spyne.model import AnyXml, Boolean, ByteArray, ComplexModel, Integer
from spyne.model import Mandatory as M
-from spyne.model import Unicode
-from spyne.model import Uuid
-from spyne.model import Boolean
+from spyne.model import Unicode, Uuid, XmlAttribute, XmlData
from spyne.protocol.soap import Soap11, Soap12
from spyne.service import Service
-from spyne.util.xml import get_schema_documents
-from spyne.util.xml import parse_schema_element
-from spyne.util.xml import parse_schema_string
-
-from spyne.interface.xml_schema import XmlSchema
-from spyne.interface.xml_schema.genpy import CodeGenerator
+from spyne.util.xml import (
+ get_schema_documents,
+ parse_schema_element,
+ parse_schema_string,
+)
class TestXmlSchema(unittest.TestCase):
@@ -61,68 +54,95 @@ class KickassService(Service):
def wooo(ctx):
return SomeObject()
- Application([KickassService],
- tns='kickass.ns',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11()
+ Application(
+ [KickassService],
+ tns="kickass.ns",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
)
docs = get_schema_documents([SomeObject])
- doc = docs['tns']
+ doc = docs["tns"]
print(etree.tostring(doc, pretty_print=True))
- assert len(doc.xpath('/xs:schema/xs:complexType[@name="SomeObject"]'
- '/xs:sequence/xs:element[@name="punk"]',
- namespaces={'xs': NS_XSD})) > 0
- assert len(doc.xpath('/xs:schema/xs:complexType[@name="SomeObject"]'
+ assert (
+ len(
+ doc.xpath(
+ '/xs:schema/xs:complexType[@name="SomeObject"]'
+ '/xs:sequence/xs:element[@name="punk"]',
+ namespaces={"xs": NS_XSD},
+ )
+ )
+ > 0
+ )
+ assert (
+ len(
+ doc.xpath(
+ '/xs:schema/xs:complexType[@name="SomeObject"]'
'/xs:sequence/xs:choice/xs:element[@name="one"]',
- namespaces={'xs': NS_XSD})) > 0
+ namespaces={"xs": NS_XSD},
+ )
+ )
+ > 0
+ )
def test_customized_class_with_empty_subclass(self):
class SummaryStatsOfDouble(ComplexModel):
- _type_info = [('Min', XmlAttribute(Integer, use='required')),
- ('Max', XmlAttribute(Integer, use='required')),
- ('Avg', XmlAttribute(Integer, use='required'))]
+ _type_info = [
+ ("Min", XmlAttribute(Integer, use="required")),
+ ("Max", XmlAttribute(Integer, use="required")),
+ ("Avg", XmlAttribute(Integer, use="required")),
+ ]
class SummaryStats(SummaryStatsOfDouble):
- ''' this is an empty base class '''
+ """this is an empty base class"""
class Payload(ComplexModel):
- _type_info = [('Stat1', SummaryStats.customize(nillable=False)),
- ('Stat2', SummaryStats),
- ('Stat3', SummaryStats),
- ('Dummy', Unicode)]
+ _type_info = [
+ ("Stat1", SummaryStats.customize(nillable=False)),
+ ("Stat2", SummaryStats),
+ ("Stat3", SummaryStats),
+ ("Dummy", Unicode),
+ ]
class JackedUpService(Service):
@rpc(_returns=Payload)
def GetPayload(ctx):
return Payload()
- Application([JackedUpService],
- tns='kickass.ns',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11()
+ Application(
+ [JackedUpService],
+ tns="kickass.ns",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
)
# if no exceptions while building the schema, no problem.
# see: https://github.com/arskom/spyne/issues/226
-
def test_namespaced_xml_attribute(self):
class Release(ComplexModel):
__namespace__ = "http://usefulinc.com/ns/doap#"
_type_info = [
- ('about', XmlAttribute(Unicode,
- ns="http://www.w3.org/1999/02/22-rdf-syntax-ns#")),
+ (
+ "about",
+ XmlAttribute(
+ Unicode, ns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ ),
+ ),
]
class Project(ComplexModel):
__namespace__ = "http://usefulinc.com/ns/doap#"
_type_info = [
- ('about', XmlAttribute(Unicode,
- ns="http://www.w3.org/1999/02/22-rdf-syntax-ns#")),
- ('release', Release.customize(max_occurs=float('inf'))),
+ (
+ "about",
+ XmlAttribute(
+ Unicode, ns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ ),
+ ),
+ ("release", Release.customize(max_occurs=float("inf"))),
]
class RdfService(Service):
@@ -130,17 +150,18 @@ class RdfService(Service):
def some_call(ctx, a, b):
pass
- Application([RdfService],
- tns='spynepi',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11()
+ Application(
+ [RdfService],
+ tns="spynepi",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
)
# if no exceptions while building the schema, no problem.
def test_customized_simple_type_in_xml_attribute(self):
class Product(ComplexModel):
- __namespace__ = 'some_ns'
+ __namespace__ = "some_ns"
id = XmlAttribute(Uuid)
edition = Unicode
@@ -148,63 +169,73 @@ class Product(ComplexModel):
class SomeService(Service):
@rpc(Product, _returns=Product)
def echo_product(ctx, product):
- logging.info('edition_id: %r', product.edition_id)
+ logging.info("edition_id: %r", product.edition_id)
return product
- Application([SomeService], tns='some_ns',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11()
+ Application(
+ [SomeService],
+ tns="some_ns",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
)
# if no exceptions while building the schema, no problem.
def test_binary_encodings(self):
class Product(ComplexModel):
- __namespace__ = 'some_ns'
+ __namespace__ = "some_ns"
- hex = ByteArray(encoding='hex')
- base64_1 = ByteArray(encoding='base64')
+ hex = ByteArray(encoding="hex")
+ base64_1 = ByteArray(encoding="base64")
base64_2 = ByteArray
class SomeService(Service):
@rpc(Product, _returns=Product)
def echo_product(ctx, product):
- logging.info('edition_id: %r', product.edition_id)
+ logging.info("edition_id: %r", product.edition_id)
return product
- app = Application([SomeService],
- tns='some_ns',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11()
+ app = Application(
+ [SomeService],
+ tns="some_ns",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
)
- _ns = {'xs': NS_XSD}
+ _ns = {"xs": NS_XSD}
pref_xs = ns.PREFMAP[NS_XSD]
xs = XmlSchema(app.interface)
xs.build_interface_document()
- elt = xs.get_interface_document()['tns'].xpath(
- '//xs:complexType[@name="Product"]',
- namespaces=_ns)[0]
+ elt = xs.get_interface_document()["tns"].xpath(
+ '//xs:complexType[@name="Product"]', namespaces=_ns
+ )[0]
- assert elt.xpath('//xs:element[@name="base64_1"]/@type',
- namespaces=_ns)[0] == '%s:base64Binary' % pref_xs
- assert elt.xpath('//xs:element[@name="base64_2"]/@type',
- namespaces=_ns)[0] == '%s:base64Binary' % pref_xs
- assert elt.xpath('//xs:element[@name="hex"]/@type',
- namespaces=_ns)[0] == '%s:hexBinary' % pref_xs
+ assert (
+ elt.xpath('//xs:element[@name="base64_1"]/@type', namespaces=_ns)[0]
+ == "%s:base64Binary" % pref_xs
+ )
+ assert (
+ elt.xpath('//xs:element[@name="base64_2"]/@type', namespaces=_ns)[0]
+ == "%s:base64Binary" % pref_xs
+ )
+ assert (
+ elt.xpath('//xs:element[@name="hex"]/@type', namespaces=_ns)[0]
+ == "%s:hexBinary" % pref_xs
+ )
def test_multilevel_customized_simple_type(self):
class ExampleService(Service):
- __tns__ = 'http://xml.company.com/ns/example/'
+ __tns__ = "http://xml.company.com/ns/example/"
@rpc(M(Uuid), _returns=Unicode)
def say_my_uuid(ctx, uuid):
- return 'Your UUID: %s' % uuid
+ return "Your UUID: %s" % uuid
- Application([ExampleService],
- tns='kickass.ns',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11()
+ Application(
+ [ExampleService],
+ tns="kickass.ns",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
)
# if no exceptions while building the schema, no problem.
@@ -216,19 +247,22 @@ def test_any_tag(self):
class SomeType(ComplexModel):
__namespace__ = "zo"
- anything = AnyXml(schema_tag='{%s}any' % NS_XSD, namespace='##other',
- process_contents='lax')
+ anything = AnyXml(
+ schema_tag="{%s}any" % NS_XSD,
+ namespace="##other",
+ process_contents="lax",
+ )
docs = get_schema_documents([SomeType])
- print(etree.tostring(docs['tns'], pretty_print=True))
- _any = docs['tns'].xpath('//xsd:any', namespaces={'xsd': NS_XSD})
+ print(etree.tostring(docs["tns"], pretty_print=True))
+ _any = docs["tns"].xpath("//xsd:any", namespaces={"xsd": NS_XSD})
assert len(_any) == 1
- assert _any[0].attrib['namespace'] == '##other'
- assert _any[0].attrib['processContents'] == 'lax'
+ assert _any[0].attrib["namespace"] == "##other"
+ assert _any[0].attrib["processContents"] == "lax"
def _build_xml_data_test_schema(self, custom_root):
- tns = 'kickass.ns'
+ tns = "kickass.ns"
class ProductEdition(ComplexModel):
__namespace__ = tns
@@ -248,27 +282,34 @@ class ExampleService(Service):
def say_my_uuid(ctx, product):
pass
- app = Application([ExampleService],
- tns='kickass.ns',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11()
+ app = Application(
+ [ExampleService],
+ tns="kickass.ns",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
)
schema = XmlSchema(app.interface)
schema.build_interface_document()
schema.build_validation_schema()
- doc = schema.get_interface_document()['tns']
+ doc = schema.get_interface_document()["tns"]
print(etree.tostring(doc, pretty_print=True))
return schema
def test_xml_data_schema_doc(self):
schema = self._build_xml_data_test_schema(custom_root=False)
- assert len(schema.get_interface_document()['tns'].xpath(
- '/xs:schema/xs:complexType[@name="ProductEdition"]'
- '/xs:simpleContent/xs:extension/xs:attribute[@name="id"]'
- ,namespaces={'xs': NS_XSD})) == 1
+ assert (
+ len(
+ schema.get_interface_document()["tns"].xpath(
+ '/xs:schema/xs:complexType[@name="ProductEdition"]'
+ '/xs:simpleContent/xs:extension/xs:attribute[@name="id"]',
+ namespaces={"xs": NS_XSD},
+ )
+ )
+ == 1
+ )
def _test_xml_data_validation(self):
schema = self._build_xml_data_test_schema(custom_root=False)
@@ -290,10 +331,11 @@ def _test_xml_data_validation_custom_root(self):
""")), schema.validation_schema.error_log.last_error
-
def test_subs(self):
from lxml import etree
+
from spyne.util.xml import get_schema_documents
+
xpath = lambda o, x: o.xpath(x, namespaces={"xs": NS_XSD})
m = {
@@ -309,10 +351,10 @@ class C(ComplexModel):
c = Integer(sub_ns="cc")
d = Integer(sub_ns="dd", sub_name="dd")
- elt = get_schema_documents([C], "aa")['tns']
+ elt = get_schema_documents([C], "aa")["tns"]
print(etree.tostring(elt, pretty_print=True))
- seq, = xpath(elt, "xs:complexType/xs:sequence")
+ (seq,) = xpath(elt, "xs:complexType/xs:sequence")
assert len(seq) == 4
assert len(xpath(seq, 'xs:element[@name="a"]')) == 1
@@ -321,8 +363,8 @@ class C(ComplexModel):
# FIXME: this doesn't feel right.
# check the spec to see whether it should it be prefixed.
#
- #assert len(xpath(seq, 'xs:element[@name="{cc}c"]')) == 1
- #assert len(xpath(seq, 'xs:element[@name="{dd}dd"]')) == 1
+ # assert len(xpath(seq, 'xs:element[@name="{cc}c"]')) == 1
+ # assert len(xpath(seq, 'xs:element[@name="{dd}dd"]')) == 1
def test_mandatory(self):
xpath = lambda o, x: o.xpath(x, namespaces={"xs": NS_XSD})
@@ -331,35 +373,37 @@ class C(ComplexModel):
__namespace__ = "aa"
foo = XmlAttribute(M(Unicode))
- elt = get_schema_documents([C])['tns']
+ elt = get_schema_documents([C])["tns"]
print(etree.tostring(elt, pretty_print=True))
- foo, = xpath(elt, 'xs:complexType/xs:attribute[@name="foo"]')
+ (foo,) = xpath(elt, 'xs:complexType/xs:attribute[@name="foo"]')
attrs = foo.attrib
- assert 'use' in attrs and attrs['use'] == 'required'
+ assert "use" in attrs and attrs["use"] == "required"
def test_annotation(self):
- tns = 'some_ns'
+ tns = "some_ns"
doc = "Some Doc"
class SomeClass(ComplexModel):
__namespace__ = tns
some_attr = Unicode(doc=doc)
- schema = get_schema_documents([SomeClass], tns)['tns']
+ schema = get_schema_documents([SomeClass], tns)["tns"]
print(etree.tostring(schema, pretty_print=True))
- assert schema.xpath("//xs:documentation/text()",
- namespaces={'xs': NS_XSD}) == [doc]
+ assert schema.xpath("//xs:documentation/text()", namespaces={"xs": NS_XSD}) == [
+ doc
+ ]
class TestParseOwnXmlSchema(unittest.TestCase):
def test_simple(self):
- tns = 'some_ns'
+ tns = "some_ns"
+
class SomeGuy(ComplexModel):
- __namespace__ = 'some_ns'
+ __namespace__ = "some_ns"
id = Integer
- schema = get_schema_documents([SomeGuy], tns)['tns']
+ schema = get_schema_documents([SomeGuy], tns)["tns"]
print(etree.tostring(schema, pretty_print=True))
objects = parse_schema_element(schema)
@@ -371,103 +415,111 @@ class SomeGuy(ComplexModel):
assert dict(NewGuy._type_info) == dict(SomeGuy._type_info)
def test_customized_unicode(self):
- tns = 'some_ns'
+ tns = "some_ns"
+
class SomeGuy(ComplexModel):
__namespace__ = tns
name = Unicode(max_len=10, pattern="a", min_len=5, default="aa")
- schema = get_schema_documents([SomeGuy], tns)['tns']
+ schema = get_schema_documents([SomeGuy], tns)["tns"]
print(etree.tostring(schema, pretty_print=True))
objects = parse_schema_element(schema)
pprint(objects[tns].types)
- NewGuy = objects['some_ns'].types["SomeGuy"]
- assert NewGuy._type_info['name'].Attributes.max_len == 10
- assert NewGuy._type_info['name'].Attributes.min_len == 5
- assert NewGuy._type_info['name'].Attributes.pattern == "a"
- assert NewGuy._type_info['name'].Attributes.default == "aa"
+ NewGuy = objects["some_ns"].types["SomeGuy"]
+ assert NewGuy._type_info["name"].Attributes.max_len == 10
+ assert NewGuy._type_info["name"].Attributes.min_len == 5
+ assert NewGuy._type_info["name"].Attributes.pattern == "a"
+ assert NewGuy._type_info["name"].Attributes.default == "aa"
def test_boolean_default(self):
- tns = 'some_ns'
+ tns = "some_ns"
+
class SomeGuy(ComplexModel):
__namespace__ = tns
bald = Boolean(default=True)
- schema = get_schema_documents([SomeGuy], tns)['tns']
+ schema = get_schema_documents([SomeGuy], tns)["tns"]
print(etree.tostring(schema, pretty_print=True))
objects = parse_schema_element(schema)
pprint(objects[tns].types)
- NewGuy = objects['some_ns'].types["SomeGuy"]
- assert NewGuy._type_info['bald'].Attributes.default == True
+ NewGuy = objects["some_ns"].types["SomeGuy"]
+ assert NewGuy._type_info["bald"].Attributes.default == True
def test_boolean_attribute_default(self):
- tns = 'some_ns'
+ tns = "some_ns"
+
class SomeGuy(ComplexModel):
__namespace__ = tns
bald = XmlAttribute(Boolean(default=True))
- schema = get_schema_documents([SomeGuy], tns)['tns']
+ schema = get_schema_documents([SomeGuy], tns)["tns"]
print(etree.tostring(schema, pretty_print=True))
objects = parse_schema_element(schema)
pprint(objects[tns].types)
- NewGuy = objects['some_ns'].types["SomeGuy"]
- assert NewGuy._type_info['bald'].Attributes.default == True
+ NewGuy = objects["some_ns"].types["SomeGuy"]
+ assert NewGuy._type_info["bald"].Attributes.default == True
def test_attribute(self):
- tns = 'some_ns'
+ tns = "some_ns"
+
class SomeGuy(ComplexModel):
__namespace__ = tns
name = XmlAttribute(Unicode)
- schema = get_schema_documents([SomeGuy], tns)['tns']
+ schema = get_schema_documents([SomeGuy], tns)["tns"]
print(etree.tostring(schema, pretty_print=True))
objects = parse_schema_element(schema)
pprint(objects)
pprint(objects[tns].types)
- NewGuy = objects['some_ns'].types["SomeGuy"]
- assert NewGuy._type_info['name'].type is Unicode
+ NewGuy = objects["some_ns"].types["SomeGuy"]
+ assert NewGuy._type_info["name"].type is Unicode
def test_attribute_with_customized_type(self):
- tns = 'some_ns'
+ tns = "some_ns"
+
class SomeGuy(ComplexModel):
__namespace__ = tns
name = XmlAttribute(Unicode(default="aa"))
- schema = get_schema_documents([SomeGuy], tns)['tns']
+ schema = get_schema_documents([SomeGuy], tns)["tns"]
print(etree.tostring(schema, pretty_print=True))
objects = parse_schema_element(schema)
pprint(objects[tns].types)
- NewGuy = objects['some_ns'].types["SomeGuy"]
- assert NewGuy._type_info['name'].type.__orig__ is Unicode
- assert NewGuy._type_info['name'].type.Attributes.default == "aa"
+ NewGuy = objects["some_ns"].types["SomeGuy"]
+ assert NewGuy._type_info["name"].type.__orig__ is Unicode
+ assert NewGuy._type_info["name"].type.Attributes.default == "aa"
def test_inherited_attribute(self):
class DeviceEntity(ComplexModel):
- token = XmlAttribute(Unicode, use='required')
+ token = XmlAttribute(Unicode, use="required")
class DigitalInput(DeviceEntity):
IdleState = XmlAttribute(Unicode)
class SomeService(Service):
- @rpc(_returns=DigitalInput, _body_style='bare')
+ @rpc(_returns=DigitalInput, _body_style="bare")
def GetDigitalInput(ctx):
return DigitalInput()
- Application([SomeService], 'some_tns',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11())
+ Application(
+ [SomeService],
+ "some_tns",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
+ )
def test_simple_type_explicit_customization(self):
class Header(ComplexModel):
@@ -480,20 +532,21 @@ class Params(ComplexModel):
class DummyService(Service):
@rpc(Params, _returns=Unicode)
def loadServices(ctx, serviceParams):
- return '42'
-
- Application([DummyService],
- tns='dummy',
- name='DummyService',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11()
+ return "42"
+
+ Application(
+ [DummyService],
+ tns="dummy",
+ name="DummyService",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
)
# if instantiation doesn't fail, test is green.
class TestParseForeignXmlSchema(unittest.TestCase):
def test_simple_content(self):
- tns = 'some_ns'
+ tns = "some_ns"
schema = """ need 2 service, 3 port and 3 bindings
- services = interface_doc.root_elt.xpath(
- '/wsdl:definitions/wsdl:service',
- namespaces = {
- 'wsdl':'http://schemas.xmlsoap.org/wsdl/' })
+ services = interface_doc.root_elt.xpath(
+ "/wsdl:definitions/wsdl:service",
+ namespaces={"wsdl": "http://schemas.xmlsoap.org/wsdl/"},
+ )
self.assertEqual(len(services), 2)
- portTypes = interface_doc.root_elt.xpath(
- '/wsdl:definitions/wsdl:portType',
- namespaces = {
- 'wsdl':'http://schemas.xmlsoap.org/wsdl/' })
+ portTypes = interface_doc.root_elt.xpath(
+ "/wsdl:definitions/wsdl:portType",
+ namespaces={"wsdl": "http://schemas.xmlsoap.org/wsdl/"},
+ )
self.assertEqual(len(portTypes), 3)
-
- bindings = interface_doc.root_elt.xpath(
- '/wsdl:definitions/wsdl:binding',
- namespaces = {
- 'wsdl':'http://schemas.xmlsoap.org/wsdl/' })
+ bindings = interface_doc.root_elt.xpath(
+ "/wsdl:definitions/wsdl:binding",
+ namespaces={"wsdl": "http://schemas.xmlsoap.org/wsdl/"},
+ )
self.assertEqual(len(bindings), 3)
- ports = interface_doc.root_elt.xpath(
- '/wsdl:definitions/wsdl:service[@name="%s"]/wsdl:port' %
- SinglePortService.__service_name__,
- namespaces = {
- 'wsdl':'http://schemas.xmlsoap.org/wsdl/' })
+ ports = interface_doc.root_elt.xpath(
+ '/wsdl:definitions/wsdl:service[@name="%s"]/wsdl:port'
+ % SinglePortService.__service_name__,
+ namespaces={"wsdl": "http://schemas.xmlsoap.org/wsdl/"},
+ )
self.assertEqual(len(ports), 1)
- ports = interface_doc.root_elt.xpath(
- '/wsdl:definitions/wsdl:service[@name="%s"]/wsdl:port' %
- "DoublePortService",
- namespaces = {
- 'wsdl':'http://schemas.xmlsoap.org/wsdl/' })
+ ports = interface_doc.root_elt.xpath(
+ '/wsdl:definitions/wsdl:service[@name="%s"]/wsdl:port'
+ % "DoublePortService",
+ namespaces={"wsdl": "http://schemas.xmlsoap.org/wsdl/"},
+ )
self.assertEqual(len(ports), 2)
# checking name and type
- #service SinglePortService
+ # service SinglePortService
for srv in (SinglePortService, DoublePortService):
for port in srv.__port_types__:
- bindings = interface_doc.root_elt.xpath(
- '/wsdl:definitions/wsdl:binding[@name="%s"]' %
- port,
- namespaces = {
- 'wsdl':'http://schemas.xmlsoap.org/wsdl/' })
- self.assertEqual(bindings[0].get('type'), "tns:%s" % port)
+ bindings = interface_doc.root_elt.xpath(
+ '/wsdl:definitions/wsdl:binding[@name="%s"]' % port,
+ namespaces={"wsdl": "http://schemas.xmlsoap.org/wsdl/"},
+ )
+ self.assertEqual(bindings[0].get("type"), "tns:%s" % port)
diff --git a/spyne/test/interface/wsdl/test_default_wsdl.py b/spyne/test/interface/wsdl/test_default_wsdl.py
index c81046e73..8c0442f9f 100755
--- a/spyne/test/interface/wsdl/test_default_wsdl.py
+++ b/spyne/test/interface/wsdl/test_default_wsdl.py
@@ -19,6 +19,7 @@
import logging
+
logging.basicConfig(level=logging.DEBUG)
import unittest
@@ -26,26 +27,21 @@
from lxml import etree
from spyne.application import Application
-
-from spyne.test.interface.wsdl import AppTestWrapper
-from spyne.test.interface.wsdl import build_app
-from spyne.test.interface.wsdl.defult_services import TDefaultPortService
-from spyne.test.interface.wsdl.defult_services import \
- TDefaultPortServiceMultipleMethods
-
-from spyne.const import REQUEST_SUFFIX
-from spyne.const import RESPONSE_SUFFIX
-from spyne.const import ARRAY_SUFFIX
-
+from spyne.const import ARRAY_SUFFIX, REQUEST_SUFFIX, RESPONSE_SUFFIX
from spyne.decorator import srpc
-from spyne.service import Service
from spyne.interface.wsdl import Wsdl11
from spyne.model.complex import Array
from spyne.model.primitive import String
+from spyne.service import Service
+from spyne.test.interface.wsdl import AppTestWrapper, build_app
+from spyne.test.interface.wsdl.defult_services import (
+ TDefaultPortService,
+ TDefaultPortServiceMultipleMethods,
+)
ns = {
- 'wsdl': 'http://schemas.xmlsoap.org/wsdl/',
- 'xs': 'http://www.w3.org/2001/XMLSchema',
+ "wsdl": "http://schemas.xmlsoap.org/wsdl/",
+ "xs": "http://www.w3.org/2001/XMLSchema",
}
@@ -58,7 +54,7 @@ def _default_service(self, app_wrapper, service_name):
# the default behavior requires that there be only a single service
self.assertEqual(1, len(services))
- self.assertEqual(service_name, service.get('name'))
+ self.assertEqual(service_name, service.get("name"))
# Test the default service has the correct number of ports
# the default behavior requires that there be only a single port
@@ -75,7 +71,7 @@ def _default_port_type(self, app_wrapper, portType_name, op_count):
# Verify the portType name
portType = portTypes[0]
# Check the name of the port
- self.assertEqual(portType_name, portType.get('name'))
+ self.assertEqual(portType_name, portType.get("name"))
# verify that the portType definition has the correct
# number of operations
@@ -89,7 +85,7 @@ def _default_binding(self, wrapper, binding_name, opp_count):
# check for the correct binding name
binding = bindings[0]
- name = binding.get('name')
+ name = binding.get("name")
self.assertEqual(binding_name, name)
# Test that the default service contains the soap binding
@@ -109,25 +105,21 @@ def _default_binding_methods(self, wrapper, op_count, op_names):
# Check the operation names are correct
for op in operations:
- self.assertTrue(op.get('name') in op_names)
+ self.assertTrue(op.get("name") in op_names)
def test_default_port_type(self):
# Test the default port is created
# Test the default port has the correct name
- app = build_app(
- [TDefaultPortService()],
- 'DefaultPortTest',
- 'DefaultPortName'
- )
+ app = build_app([TDefaultPortService()], "DefaultPortTest", "DefaultPortName")
wrapper = AppTestWrapper(app)
- self._default_port_type(wrapper, 'DefaultPortName', 1)
+ self._default_port_type(wrapper, "DefaultPortName", 1)
def test_default_port_type_multiple(self):
app = build_app(
[TDefaultPortServiceMultipleMethods()],
- 'DefaultServiceTns',
- 'MultipleDefaultPortServiceApp'
+ "DefaultServiceTns",
+ "MultipleDefaultPortServiceApp",
)
wrapper = AppTestWrapper(app)
@@ -136,9 +128,7 @@ def test_default_port_type_multiple(self):
def test_default_binding(self):
app = build_app(
- [TDefaultPortService()],
- 'DefaultPortTest',
- 'DefaultBindingName'
+ [TDefaultPortService()], "DefaultPortTest", "DefaultBindingName"
)
wrapper = AppTestWrapper(app)
@@ -148,40 +138,34 @@ def test_default_binding(self):
def test_default_binding_multiple(self):
app = build_app(
[TDefaultPortServiceMultipleMethods()],
- 'DefaultPortTest',
- 'MultipleDefaultBindingNameApp'
+ "DefaultPortTest",
+ "MultipleDefaultBindingNameApp",
)
wrapper = AppTestWrapper(app)
- self._default_binding(wrapper, 'MultipleDefaultBindingNameApp', 3)
+ self._default_binding(wrapper, "MultipleDefaultBindingNameApp", 3)
def test_default_binding_methods(self):
app = build_app(
- [TDefaultPortService()],
- 'DefaultPortTest',
- 'DefaultPortMethods'
+ [TDefaultPortService()], "DefaultPortTest", "DefaultPortMethods"
)
wrapper = AppTestWrapper(app)
- self._default_binding_methods(
- wrapper,
- 1,
- ['echo_default_port_service']
- )
+ self._default_binding_methods(wrapper, 1, ["echo_default_port_service"])
def test_bare_simple(self):
class SomeService(Service):
- @srpc(String, _returns=String, _body_style='bare')
+ @srpc(String, _returns=String, _body_style="bare")
def whatever(ss):
return ss
- app = Application([SomeService], tns='tns')
- app.transport = 'None'
+ app = Application([SomeService], tns="tns")
+ app.transport = "None"
wsdl = Wsdl11(app.interface)
- wsdl.build_interface_document('url')
+ wsdl.build_interface_document("url")
wsdl = etree.fromstring(wsdl.get_interface_document())
schema = wsdl.xpath(
@@ -193,14 +177,16 @@ def whatever(ss):
print(etree.tostring(wsdl, pretty_print=True))
elts = schema[0].xpath(
- 'xs:element[@name="whatever%s"]' % REQUEST_SUFFIX, namespaces=ns)
+ 'xs:element[@name="whatever%s"]' % REQUEST_SUFFIX, namespaces=ns
+ )
assert len(elts) > 0
- assert elts[0].attrib['type'] == 'xs:string'
+ assert elts[0].attrib["type"] == "xs:string"
elts = schema[0].xpath(
- 'xs:element[@name="whatever%s"]' % RESPONSE_SUFFIX, namespaces=ns)
+ 'xs:element[@name="whatever%s"]' % RESPONSE_SUFFIX, namespaces=ns
+ )
assert len(elts) > 0
- assert elts[0].attrib['type'] == 'xs:string'
+ assert elts[0].attrib["type"] == "xs:string"
def test_bare_with_conflicting_types(self):
class SomeService(Service):
@@ -208,41 +194,46 @@ class SomeService(Service):
def whatever(sa):
return sa
- @srpc(Array(String), _returns=Array(String), _body_style='bare')
+ @srpc(Array(String), _returns=Array(String), _body_style="bare")
def whatever_bare(sa):
return sa
- app = Application([SomeService], tns='tns')
- app.transport = 'None'
+ app = Application([SomeService], tns="tns")
+ app.transport = "None"
wsdl = Wsdl11(app.interface)
- wsdl.build_interface_document('url')
+ wsdl.build_interface_document("url")
wsdl = etree.fromstring(wsdl.get_interface_document())
- schema, = wsdl.xpath(
+ (schema,) = wsdl.xpath(
'/wsdl:definitions/wsdl:types/xs:schema[@targetNamespace="tns"]',
namespaces=ns,
)
print(etree.tostring(schema, pretty_print=True))
- assert len(schema.xpath(
- 'xs:complexType[@name="string%s"]' % ARRAY_SUFFIX,
- namespaces=ns)) > 0
+ assert (
+ len(
+ schema.xpath(
+ 'xs:complexType[@name="string%s"]' % ARRAY_SUFFIX, namespaces=ns
+ )
+ )
+ > 0
+ )
elts = schema.xpath(
- 'xs:element[@name="whatever_bare%s"]' % REQUEST_SUFFIX,
- namespaces=ns)
+ 'xs:element[@name="whatever_bare%s"]' % REQUEST_SUFFIX, namespaces=ns
+ )
assert len(elts) > 0
- assert elts[0].attrib['type'] == 'tns:string%s' % ARRAY_SUFFIX
+ assert elts[0].attrib["type"] == "tns:string%s" % ARRAY_SUFFIX
elts = schema.xpath(
- 'xs:element[@name="whatever_bare%s"]' % RESPONSE_SUFFIX,
- namespaces=ns)
+ 'xs:element[@name="whatever_bare%s"]' % RESPONSE_SUFFIX, namespaces=ns
+ )
assert len(elts) > 0
- assert elts[0].attrib['type'] == 'tns:string%s' % ARRAY_SUFFIX
+ assert elts[0].attrib["type"] == "tns:string%s" % ARRAY_SUFFIX
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/interface/wsdl/test_op_req_suffix.py b/spyne/test/interface/wsdl/test_op_req_suffix.py
index 141395b74..00d986b5b 100755
--- a/spyne/test/interface/wsdl/test_op_req_suffix.py
+++ b/spyne/test/interface/wsdl/test_op_req_suffix.py
@@ -21,19 +21,19 @@
from webtest import TestApp as _TestApp # avoid confusing py.test
from spyne.application import Application
+from spyne.const.xml import NS_WSDL11_SOAP, PREFMAP
from spyne.decorator import srpc
-from spyne.service import Service
-from spyne.model.primitive import Integer, Unicode
from spyne.model.complex import Iterable
-from spyne.protocol.soap import Soap11
+from spyne.model.primitive import Integer, Unicode
from spyne.protocol.http import HttpRpc
from spyne.protocol.json import JsonDocument
+from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication
+from spyne.service import Service
-from spyne.const.xml import PREFMAP, NS_WSDL11_SOAP
def strip_whitespace(string):
- return ''.join(string.split())
+ return "".join(string.split())
class TestOperationRequestSuffix(unittest.TestCase):
@@ -42,10 +42,10 @@ class TestOperationRequestSuffix(unittest.TestCase):
_in_message_name is a concern, will test that as well
"""
- default_function_name = 'echo'
+ default_function_name = "echo"
# output is not affected, will use soap output for all tests
- result_body = '''
+ result_body = """
@@ -53,10 +53,9 @@ class TestOperationRequestSuffix(unittest.TestCase):
Echo, test
- '''
+ """
- def get_function_names(self, suffix, _operation_name=None,
- _in_message_name=None):
+ def get_function_names(self, suffix, _operation_name=None, _in_message_name=None):
"""This tests the logic of how names are produced.
Its logic should match expected behavior of the decorator.
returns operation name, in message name, service name depending on
@@ -75,37 +74,38 @@ def get_function_names(self, suffix, _operation_name=None,
return function_name, operation_name, request_name
- def get_app(self, in_protocol, suffix, _operation_name=None,
- _in_message_name=None):
+ def get_app(self, in_protocol, suffix, _operation_name=None, _in_message_name=None):
"""setup testapp dependent on suffix and _in_message_name"""
import spyne.const
+
spyne.const.REQUEST_SUFFIX = suffix
class EchoService(Service):
- srpc_kparams = {'_returns': Iterable(Unicode)}
+ srpc_kparams = {"_returns": Iterable(Unicode)}
if _in_message_name:
- srpc_kparams['_in_message_name'] = _in_message_name
+ srpc_kparams["_in_message_name"] = _in_message_name
if _operation_name:
- srpc_kparams['_operation_name'] = _operation_name
+ srpc_kparams["_operation_name"] = _operation_name
@srpc(Unicode, Integer, **srpc_kparams)
def echo(string, times):
for i in range(times):
- yield 'Echo, %s' % string
+ yield "Echo, %s" % string
- application = Application([EchoService],
- tns='spyne.examples.echo',
+ application = Application(
+ [EchoService],
+ tns="spyne.examples.echo",
in_protocol=in_protocol,
- out_protocol=Soap11()
+ out_protocol=Soap11(),
)
app = WsgiApplication(application)
testapp = _TestApp(app)
# so that it doesn't interfere with other tests.
- spyne.const.REQUEST_SUFFIX = ''
+ spyne.const.REQUEST_SUFFIX = ""
return testapp
@@ -114,32 +114,42 @@ def assert_response_ok(self, resp):
self.assertEqual(resp.status_int, 200, resp)
self.assertTrue(
strip_whitespace(self.result_body) in strip_whitespace(str(resp)),
- '{0} not in {1}'.format(self.result_body, resp))
+ "{0} not in {1}".format(self.result_body, resp),
+ )
### application error tests ###
- def assert_application_error(self, suffix, _operation_name=None,
- _in_message_name=None):
- self.assertRaises(ValueError,
- self.get_app, Soap11(validator='lxml'), suffix,
- _operation_name, _in_message_name)
+ def assert_application_error(
+ self, suffix, _operation_name=None, _in_message_name=None
+ ):
+ self.assertRaises(
+ ValueError,
+ self.get_app,
+ Soap11(validator="lxml"),
+ suffix,
+ _operation_name,
+ _in_message_name,
+ )
def test_assert_application_error(self):
"""check error when op namd and in name are both used"""
- self.assert_application_error(suffix='',
- _operation_name='TestOperationName',
- _in_message_name='TestMessageName')
+ self.assert_application_error(
+ suffix="",
+ _operation_name="TestOperationName",
+ _in_message_name="TestMessageName",
+ )
### soap tests ###
- def assert_soap_ok(self, suffix, _operation_name=None,
- _in_message_name=None):
+ def assert_soap_ok(self, suffix, _operation_name=None, _in_message_name=None):
"""helper to test soap requests"""
# setup
- app = self.get_app(Soap11(validator='lxml'), suffix, _operation_name,
- _in_message_name)
+ app = self.get_app(
+ Soap11(validator="lxml"), suffix, _operation_name, _in_message_name
+ )
function_name, operation_name, request_name = self.get_function_names(
- suffix, _operation_name, _in_message_name)
+ suffix, _operation_name, _in_message_name
+ )
soap_input_body = """
""".format(request_name)
# check wsdl
- wsdl = app.get('/?wsdl')
+ wsdl = app.get("/?wsdl")
self.assertEqual(wsdl.status_int, 200, wsdl)
- self.assertTrue(request_name in wsdl,
- '{0} not found in wsdl'.format(request_name))
+ self.assertTrue(
+ request_name in wsdl, "{0} not found in wsdl".format(request_name)
+ )
soap_strings = [
''.format(request_name),
''.format(request_name),
]
for soap_string in soap_strings:
- self.assertTrue(soap_string in wsdl,
- '{0} not in {1}'.format(soap_string, wsdl))
+ self.assertTrue(
+ soap_string in wsdl, "{0} not in {1}".format(soap_string, wsdl)
+ )
if request_name != operation_name:
wrong_string = '= 2.5")
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/spyne/test/interop/server/httprpc_pod_basic_twisted.py b/spyne/test/interop/server/httprpc_pod_basic_twisted.py
index 6e824f408..fb349f96c 100755
--- a/spyne/test/interop/server/httprpc_pod_basic_twisted.py
+++ b/spyne/test/interop/server/httprpc_pod_basic_twisted.py
@@ -20,28 +20,34 @@
"""pod being plain old data"""
import logging
+
logging.basicConfig(level=logging.DEBUG)
-logger = logging.getLogger('spyne.protocol.xml')
+logger = logging.getLogger("spyne.protocol.xml")
logger.setLevel(logging.DEBUG)
-from spyne.test.interop.server import get_open_port
from spyne.application import Application
-from spyne.test.interop.server._service import services
from spyne.protocol.http import HttpRpc
from spyne.server.twisted import TwistedWebResource
+from spyne.test.interop.server import get_open_port
+from spyne.test.interop.server._service import services
-httprpc_soap_application = Application(services,
- 'spyne.test.interop.server.httprpc.pod',
- in_protocol=HttpRpc(), out_protocol=HttpRpc())
+httprpc_soap_application = Application(
+ services,
+ "spyne.test.interop.server.httprpc.pod",
+ in_protocol=HttpRpc(),
+ out_protocol=HttpRpc(),
+)
-host = '127.0.0.1'
+host = "127.0.0.1"
port = [0]
+
def main(argv):
- from twisted.web.server import Site
from twisted.internet import reactor
from twisted.python import log
- observer = log.PythonLoggingObserver('twisted')
+ from twisted.web.server import Site
+
+ observer = log.PythonLoggingObserver("twisted")
log.startLoggingWithObserver(observer.emit, setStdout=False)
if port[0] == 0:
@@ -51,11 +57,12 @@ def main(argv):
site = Site(wr)
reactor.listenTCP(port[0], site)
- logging.info("listening on: %s:%d" % (host,port[0]))
+ logging.info("listening on: %s:%d" % (host, port[0]))
return reactor.run()
-if __name__ == '__main__':
+if __name__ == "__main__":
import sys
+
sys.exit(main(sys.argv))
diff --git a/spyne/test/interop/server/msgpackrpc_http_basic.py b/spyne/test/interop/server/msgpackrpc_http_basic.py
index d19e869f9..53880b911 100644
--- a/spyne/test/interop/server/msgpackrpc_http_basic.py
+++ b/spyne/test/interop/server/msgpackrpc_http_basic.py
@@ -18,39 +18,46 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
-logging.getLogger('spyne.protocol.msgpack').setLevel(logging.DEBUG)
-logger = logging.getLogger('spyne.test.interop.server.msgpackrpc_http_basic')
+logging.getLogger("spyne.protocol.msgpack").setLevel(logging.DEBUG)
+logger = logging.getLogger("spyne.test.interop.server.msgpackrpc_http_basic")
-from spyne.test.interop.server import get_open_port
-from spyne.server.wsgi import WsgiApplication
-from spyne.test.interop.server._service import services
from spyne.application import Application
from spyne.protocol.msgpack import MessagePackRpc
+from spyne.server.wsgi import WsgiApplication
+from spyne.test.interop.server import get_open_port
+from spyne.test.interop.server._service import services
-msgpackrpc_application = Application(services, 'spyne.test.interop.server',
- in_protocol=MessagePackRpc(validator='soft'),
- out_protocol=MessagePackRpc())
+msgpackrpc_application = Application(
+ services,
+ "spyne.test.interop.server",
+ in_protocol=MessagePackRpc(validator="soft"),
+ out_protocol=MessagePackRpc(),
+)
-host = '127.0.0.1'
+host = "127.0.0.1"
port = [0]
+
def main():
try:
from wsgiref.simple_server import make_server
from wsgiref.validate import validator
+
if port[0] == 0:
port[0] = get_open_port()
wsgi_application = WsgiApplication(msgpackrpc_application)
server = make_server(host, port[0], validator(wsgi_application))
- logger.info('Starting interop server at %s:%s.' % (host, port[0]))
- logger.info('WSDL is at: /?wsdl')
+ logger.info("Starting interop server at %s:%s." % (host, port[0]))
+ logger.info("WSDL is at: /?wsdl")
server.serve_forever()
except ImportError:
print("Error: example server code requires Python >= 2.5")
-if __name__ == '__main__':
+
+if __name__ == "__main__":
main()
diff --git a/spyne/test/interop/server/soap11/httprpc_soap_basic.py b/spyne/test/interop/server/soap11/httprpc_soap_basic.py
index 3969598bc..595b9a11f 100755
--- a/spyne/test/interop/server/soap11/httprpc_soap_basic.py
+++ b/spyne/test/interop/server/soap11/httprpc_soap_basic.py
@@ -18,38 +18,43 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
-logger = logging.getLogger('spyne.protocol.xml')
+logger = logging.getLogger("spyne.protocol.xml")
logger.setLevel(logging.DEBUG)
from spyne.application import Application
-from spyne.test.interop.server._service import services
from spyne.protocol.http import HttpRpc
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication
from spyne.test.interop.server import get_open_port
+from spyne.test.interop.server._service import services
-
-httprpc_soap_application = Application(services,
- 'spyne.test.interop.server.httprpc.soap', in_protocol=HttpRpc(), out_protocol=Soap11())
+httprpc_soap_application = Application(
+ services,
+ "spyne.test.interop.server.httprpc.soap",
+ in_protocol=HttpRpc(),
+ out_protocol=Soap11(),
+)
-host = '127.0.0.1'
+host = "127.0.0.1"
port = [0]
-if __name__ == '__main__':
+if __name__ == "__main__":
try:
from wsgiref.simple_server import make_server
from wsgiref.validate import validator
+
if port[0] == 0:
port[0] = get_open_port()
wsgi_application = WsgiApplication(httprpc_soap_application)
server = make_server(host, port[0], validator(wsgi_application))
- logger.info('Starting interop server at %s:%s.' % ('0.0.0.0', port[0]))
- logger.info('WSDL is at: /?wsdl')
+ logger.info("Starting interop server at %s:%s." % ("0.0.0.0", port[0]))
+ logger.info("WSDL is at: /?wsdl")
server.serve_forever()
except ImportError:
diff --git a/spyne/test/interop/server/soap11/soap_http_basic.py b/spyne/test/interop/server/soap11/soap_http_basic.py
index 65a86057d..433e57d7f 100755
--- a/spyne/test/interop/server/soap11/soap_http_basic.py
+++ b/spyne/test/interop/server/soap11/soap_http_basic.py
@@ -20,23 +20,25 @@
import logging
logging.basicConfig(level=logging.DEBUG)
-logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
-logger = logging.getLogger('spyne.test.interop.server.soap_http_basic')
+logging.getLogger("spyne.protocol.xml").setLevel(logging.DEBUG)
+logger = logging.getLogger("spyne.test.interop.server.soap_http_basic")
-from spyne.test.interop.server import get_open_port
-from spyne.server.wsgi import WsgiApplication
-from spyne.test.interop.server._service import services
from spyne.application import Application
from spyne.protocol.soap import Soap11
+from spyne.server.wsgi import WsgiApplication
+from spyne.test.interop.server import get_open_port
+from spyne.test.interop.server._service import services
-
-soap11_application = Application(services, 'spyne.test.interop.server',
- in_protocol=Soap11(validator='lxml', cleanup_namespaces=True),
- out_protocol=Soap11())
+soap11_application = Application(
+ services,
+ "spyne.test.interop.server",
+ in_protocol=Soap11(validator="lxml", cleanup_namespaces=True),
+ out_protocol=Soap11(),
+)
-host = '127.0.0.1'
+host = "127.0.0.1"
port = [0]
@@ -44,19 +46,20 @@ def main():
try:
from wsgiref.simple_server import make_server
from wsgiref.validate import validator
+
if port[0] == 0:
port[0] = get_open_port()
wsgi_application = WsgiApplication(soap11_application)
server = make_server(host, port[0], validator(wsgi_application))
- logger.info('Starting interop server at %s:%s.' % ('0.0.0.0', port[0]))
- logger.info('WSDL is at: /?wsdl')
+ logger.info("Starting interop server at %s:%s." % ("0.0.0.0", port[0]))
+ logger.info("WSDL is at: /?wsdl")
server.serve_forever()
except ImportError:
print("Error: example server code requires Python >= 2.5")
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/spyne/test/interop/server/soap11/soap_http_basic_twisted.py b/spyne/test/interop/server/soap11/soap_http_basic_twisted.py
index b9d502b49..734608621 100755
--- a/spyne/test/interop/server/soap11/soap_http_basic_twisted.py
+++ b/spyne/test/interop/server/soap11/soap_http_basic_twisted.py
@@ -18,25 +18,25 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
-logger = logging.getLogger('spyne.wsgi')
+logger = logging.getLogger("spyne.wsgi")
logger.setLevel(logging.DEBUG)
+from spyne.server.twisted import TwistedWebResource
from spyne.test.interop.server import get_open_port
from spyne.test.interop.server.soap_http_basic import soap11_application
-from spyne.server.twisted import TwistedWebResource
-
-host = '127.0.0.1'
+host = "127.0.0.1"
port = [0]
def main(argv):
- from twisted.web.server import Site
from twisted.internet import reactor
from twisted.python import log
+ from twisted.web.server import Site
- observer = log.PythonLoggingObserver('twisted')
+ observer = log.PythonLoggingObserver("twisted")
log.startLoggingWithObserver(observer.emit, setStdout=False)
wr = TwistedWebResource(soap11_application)
@@ -45,10 +45,12 @@ def main(argv):
if port[0] == 0:
port[0] = get_open_port()
reactor.listenTCP(port[0], site)
- logging.info("listening on: %s:%d" % (host,port[0]))
+ logging.info("listening on: %s:%d" % (host, port[0]))
return reactor.run()
-if __name__ == '__main__':
+
+if __name__ == "__main__":
import sys
+
sys.exit(main(sys.argv))
diff --git a/spyne/test/interop/server/soap11/soap_http_static.py b/spyne/test/interop/server/soap11/soap_http_static.py
index 0e8e26ed9..ee7164ba0 100755
--- a/spyne/test/interop/server/soap11/soap_http_static.py
+++ b/spyne/test/interop/server/soap11/soap_http_static.py
@@ -18,33 +18,32 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
-logger = logging.getLogger('spyne.wsgi')
+logger = logging.getLogger("spyne.wsgi")
logger.setLevel(logging.DEBUG)
import os
+from spyne.server.twisted import TwistedWebResource
from spyne.test.interop.server import get_open_port
from spyne.test.interop.server.soap_http_basic import soap11_application
-from spyne.server.twisted import TwistedWebResource
-
-host = '127.0.0.1'
+host = "127.0.0.1"
port = [0]
-url = 'app'
+url = "app"
def main(argv):
+ from twisted.internet import reactor
from twisted.python import log
from twisted.web.server import Site
from twisted.web.static import File
- from twisted.internet import reactor
- from twisted.python import log
- observer = log.PythonLoggingObserver('twisted')
+ observer = log.PythonLoggingObserver("twisted")
log.startLoggingWithObserver(observer.emit, setStdout=False)
- static_dir = os.path.abspath('.')
+ static_dir = os.path.abspath(".")
logging.info("registering static folder %r on /" % static_dir)
root = File(static_dir)
@@ -57,11 +56,12 @@ def main(argv):
if port[0] == 0:
port[0] = get_open_port()
reactor.listenTCP(port[0], site)
- logging.info("listening on: %s:%d" % (host,port))
+ logging.info("listening on: %s:%d" % (host, port))
return reactor.run()
-if __name__ == '__main__':
+if __name__ == "__main__":
import sys
+
sys.exit(main(sys.argv))
diff --git a/spyne/test/interop/server/soap11/soap_zeromq.py b/spyne/test/interop/server/soap11/soap_zeromq.py
index 5cb7f4d49..e61eeef26 100755
--- a/spyne/test/interop/server/soap11/soap_zeromq.py
+++ b/spyne/test/interop/server/soap11/soap_zeromq.py
@@ -19,13 +19,11 @@
import logging
+from spyne.server.zeromq import ZeroMQServer
from spyne.test.interop.server import get_open_port
from spyne.test.interop.server.soap11.soap_http_basic import soap11_application
-from spyne.server.zeromq import ZeroMQServer
-
-
-host = '127.0.0.1'
+host = "127.0.0.1"
port = [0]
@@ -35,18 +33,20 @@ def main():
url = "tcp://%s:%d" % (host, port[0])
logging.basicConfig(level=logging.DEBUG)
- logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
+ logging.getLogger("spyne.protocol.xml").setLevel(logging.DEBUG)
server = ZeroMQServer(soap11_application, url)
logging.info("************************")
logging.info("Use Ctrl+\\ to exit if Ctrl-C does not work.")
- logging.info("See the 'I can't Ctrl-C my Python/Ruby application. Help!' "
- "question in http://www.zeromq.org/area:faq for more info.")
+ logging.info(
+ "See the 'I can't Ctrl-C my Python/Ruby application. Help!' "
+ "question in http://www.zeromq.org/area:faq for more info."
+ )
logging.info("listening on %r" % url)
logging.info("************************")
server.serve_forever()
-if __name__ == '__main__':
- main()
\ No newline at end of file
+if __name__ == "__main__":
+ main()
diff --git a/spyne/test/interop/server/soap12/httprpc_soap_basic.py b/spyne/test/interop/server/soap12/httprpc_soap_basic.py
index c3bc5b190..5cbd8f429 100755
--- a/spyne/test/interop/server/soap12/httprpc_soap_basic.py
+++ b/spyne/test/interop/server/soap12/httprpc_soap_basic.py
@@ -18,23 +18,28 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
-logger = logging.getLogger('spyne.protocol.xml')
+logger = logging.getLogger("spyne.protocol.xml")
logger.setLevel(logging.DEBUG)
from spyne.application import Application
-from spyne.test.interop.server._service import services
from spyne.protocol.http import HttpRpc
from spyne.protocol.soap import Soap12
from spyne.server.wsgi import WsgiApplication
+from spyne.test.interop.server._service import services
-httprpc_soap_application = Application(services,
- 'spyne.test.interop.server.httprpc.soap', in_protocol=HttpRpc(), out_protocol=Soap12())
+httprpc_soap_application = Application(
+ services,
+ "spyne.test.interop.server.httprpc.soap",
+ in_protocol=HttpRpc(),
+ out_protocol=Soap12(),
+)
-host = '127.0.0.1'
+host = "127.0.0.1"
port = 9753
-if __name__ == '__main__':
+if __name__ == "__main__":
try:
from wsgiref.simple_server import make_server
from wsgiref.validate import validator
@@ -42,8 +47,8 @@
wsgi_application = WsgiApplication(httprpc_soap_application)
server = make_server(host, port, validator(wsgi_application))
- logger.info('Starting interop server at %s:%s.' % ('0.0.0.0', 9753))
- logger.info('WSDL is at: /?wsdl')
+ logger.info("Starting interop server at %s:%s." % ("0.0.0.0", 9753))
+ logger.info("WSDL is at: /?wsdl")
server.serve_forever()
except ImportError:
diff --git a/spyne/test/interop/server/soap12/soap_http_basic.py b/spyne/test/interop/server/soap12/soap_http_basic.py
index 27fe6f037..a8d9a24aa 100755
--- a/spyne/test/interop/server/soap12/soap_http_basic.py
+++ b/spyne/test/interop/server/soap12/soap_http_basic.py
@@ -20,22 +20,25 @@
import logging
logging.basicConfig(level=logging.DEBUG)
-logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
-logger = logging.getLogger('spyne.test.interop.server.soap_http_basic')
+logging.getLogger("spyne.protocol.xml").setLevel(logging.DEBUG)
+logger = logging.getLogger("spyne.test.interop.server.soap_http_basic")
-from spyne.server.wsgi import WsgiApplication
-from spyne.test.interop.server._service import services
from spyne.application import Application
from spyne.protocol.soap import Soap12
+from spyne.server.wsgi import WsgiApplication
+from spyne.test.interop.server._service import services
+soap12_application = Application(
+ services,
+ "spyne.test.interop.server",
+ in_protocol=Soap12(validator="lxml", cleanup_namespaces=True),
+ out_protocol=Soap12(),
+)
-soap12_application = Application(services, 'spyne.test.interop.server',
- in_protocol=Soap12(validator='lxml', cleanup_namespaces=True),
- out_protocol=Soap12())
-
-host = '127.0.0.1'
+host = "127.0.0.1"
port = 9754
+
def main():
try:
from wsgiref.simple_server import make_server
@@ -44,12 +47,13 @@ def main():
wsgi_application = WsgiApplication(soap12_application)
server = make_server(host, port, validator(wsgi_application))
- logger.info('Starting interop server at %s:%s.' % ('0.0.0.0', 9754))
- logger.info('WSDL is at: /?wsdl')
+ logger.info("Starting interop server at %s:%s." % ("0.0.0.0", 9754))
+ logger.info("WSDL is at: /?wsdl")
server.serve_forever()
except ImportError:
print("Error: example server code requires Python >= 2.5")
-if __name__ == '__main__':
+
+if __name__ == "__main__":
main()
diff --git a/spyne/test/interop/server/soap12/soap_http_basic_twisted.py b/spyne/test/interop/server/soap12/soap_http_basic_twisted.py
index d115e2f97..fbaa34744 100755
--- a/spyne/test/interop/server/soap12/soap_http_basic_twisted.py
+++ b/spyne/test/interop/server/soap12/soap_http_basic_twisted.py
@@ -18,32 +18,36 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
-logger = logging.getLogger('spyne.wsgi')
+logger = logging.getLogger("spyne.wsgi")
logger.setLevel(logging.DEBUG)
-from spyne.test.interop.server.soap12.soap_http_basic import soap12_application
from spyne.server.twisted import TwistedWebResource
+from spyne.test.interop.server.soap12.soap_http_basic import soap12_application
-host = '127.0.0.1'
+host = "127.0.0.1"
port = 9755
+
def main(argv):
- from twisted.web.server import Site
from twisted.internet import reactor
from twisted.python import log
+ from twisted.web.server import Site
- observer = log.PythonLoggingObserver('twisted')
+ observer = log.PythonLoggingObserver("twisted")
log.startLoggingWithObserver(observer.emit, setStdout=False)
wr = TwistedWebResource(soap12_application)
site = Site(wr)
reactor.listenTCP(port, site)
- logging.info("listening on: %s:%d" % (host,port))
+ logging.info("listening on: %s:%d" % (host, port))
return reactor.run()
-if __name__ == '__main__':
+
+if __name__ == "__main__":
import sys
+
sys.exit(main(sys.argv))
diff --git a/spyne/test/interop/server/soap12/soap_http_static.py b/spyne/test/interop/server/soap12/soap_http_static.py
index 6cc742fda..f1b72d753 100755
--- a/spyne/test/interop/server/soap12/soap_http_static.py
+++ b/spyne/test/interop/server/soap12/soap_http_static.py
@@ -18,30 +18,31 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
-logger = logging.getLogger('spyne.wsgi')
+logger = logging.getLogger("spyne.wsgi")
logger.setLevel(logging.DEBUG)
import os
-from spyne.test.interop.server.soap12.soap_http_basic import soap12_application
from spyne.server.twisted import TwistedWebResource
+from spyne.test.interop.server.soap12.soap_http_basic import soap12_application
-host = '127.0.0.1'
+host = "127.0.0.1"
port = 9756
-url = 'app'
+url = "app"
+
def main(argv):
+ from twisted.internet import reactor
from twisted.python import log
from twisted.web.server import Site
from twisted.web.static import File
- from twisted.internet import reactor
- from twisted.python import log
- observer = log.PythonLoggingObserver('twisted')
+ observer = log.PythonLoggingObserver("twisted")
log.startLoggingWithObserver(observer.emit, setStdout=False)
- static_dir = os.path.abspath('.')
+ static_dir = os.path.abspath(".")
logging.info("registering static folder %r on /" % static_dir)
root = File(static_dir)
@@ -52,11 +53,12 @@ def main(argv):
site = Site(root)
reactor.listenTCP(port, site)
- logging.info("listening on: %s:%d" % (host,port))
+ logging.info("listening on: %s:%d" % (host, port))
return reactor.run()
-if __name__ == '__main__':
+if __name__ == "__main__":
import sys
+
sys.exit(main(sys.argv))
diff --git a/spyne/test/interop/server/soap12/soap_zeromq.py b/spyne/test/interop/server/soap12/soap_zeromq.py
index 62c2b730c..b7ceb1d89 100755
--- a/spyne/test/interop/server/soap12/soap_zeromq.py
+++ b/spyne/test/interop/server/soap12/soap_zeromq.py
@@ -19,28 +19,31 @@
import logging
-from spyne.test.interop.server.soap12.soap_http_basic import soap12_application
-
from spyne.server.zeromq import ZeroMQServer
+from spyne.test.interop.server.soap12.soap_http_basic import soap12_application
-host = '127.0.0.1'
+host = "127.0.0.1"
port = 55555
+
def main():
- url = "tcp://%s:%d" % (host,port)
+ url = "tcp://%s:%d" % (host, port)
logging.basicConfig(level=logging.DEBUG)
- logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
+ logging.getLogger("spyne.protocol.xml").setLevel(logging.DEBUG)
server = ZeroMQServer(soap12_application, url)
logging.info("************************")
logging.info("Use Ctrl+\\ to exit if Ctrl-C does not work.")
- logging.info("See the 'I can't Ctrl-C my Python/Ruby application. Help!' "
- "question in http://www.zeromq.org/area:faq for more info.")
+ logging.info(
+ "See the 'I can't Ctrl-C my Python/Ruby application. Help!' "
+ "question in http://www.zeromq.org/area:faq for more info."
+ )
logging.info("listening on %r" % url)
logging.info("************************")
server.serve_forever()
-if __name__ == '__main__':
- main()
\ No newline at end of file
+
+if __name__ == "__main__":
+ main()
diff --git a/spyne/test/interop/test_django.py b/spyne/test/interop/test_django.py
index b5df8b511..ad92142f6 100755
--- a/spyne/test/interop/test_django.py
+++ b/spyne/test/interop/test_django.py
@@ -23,99 +23,95 @@
import datetime
import re
+
from django.core.exceptions import ImproperlyConfigured
-from django.test import TestCase, TransactionTestCase, Client
+from django.test import Client, TestCase, TransactionTestCase
+from rpctest.core.models import FieldContainer, RelatedFieldContainer
+from rpctest.core.models import UserProfile as DjUserProfile
+from rpctest.core.views import Container, app, hello_world_service
from spyne.client.django import DjangoTestClient
-from spyne.model.fault import Fault
from spyne.model.complex import ComplexModelBase
-from spyne.util.django import (DjangoComplexModel, DjangoComplexModelMeta,
- email_re)
-from spyne.util.six import add_metaclass
-
-from rpctest.core.models import (FieldContainer, RelatedFieldContainer,
- UserProfile as DjUserProfile)
-from rpctest.core.views import app, hello_world_service, Container
+from spyne.model.fault import Fault
+from spyne.util.django import DjangoComplexModel, DjangoComplexModelMeta, email_re
class SpyneTestCase(TransactionTestCase):
def setUp(self):
- self.client = DjangoTestClient('/hello_world/', hello_world_service.app)
+ self.client = DjangoTestClient("/hello_world/", hello_world_service.app)
def _test_say_hello(self):
- resp = self.client.service.say_hello('Joe', 5)
+ resp = self.client.service.say_hello("Joe", 5)
list_resp = list(resp)
self.assertEqual(len(list_resp), 5)
- self.assertEqual(list_resp, ['Hello, Joe'] * 5)
+ self.assertEqual(list_resp, ["Hello, Joe"] * 5)
class DjangoViewTestCase(TestCase):
def test_say_hello(self):
- client = DjangoTestClient('/say_hello/', app)
- resp = client.service.say_hello('Joe', 5)
+ client = DjangoTestClient("/say_hello/", app)
+ resp = client.service.say_hello("Joe", 5)
list_resp = list(resp)
self.assertEqual(len(list_resp), 5)
- self.assertEqual(list_resp, ['Hello, Joe'] * 5)
+ self.assertEqual(list_resp, ["Hello, Joe"] * 5)
def test_response_encoding(self):
- client = DjangoTestClient('/say_hello/', app)
- response = client.service.say_hello.get_django_response('Joe', 5)
- self.assertTrue('Content-Type' in response)
- self.assertTrue(response['Content-Type'].startswith('text/xml'))
+ client = DjangoTestClient("/say_hello/", app)
+ response = client.service.say_hello.get_django_response("Joe", 5)
+ self.assertTrue("Content-Type" in response)
+ self.assertTrue(response["Content-Type"].startswith("text/xml"))
def test_error(self):
client = Client()
- response = client.post('/say_hello/', {})
- self.assertContains(response, 'faultstring', status_code=500)
+ response = client.post("/say_hello/", {})
+ self.assertContains(response, "faultstring", status_code=500)
def test_cached_wsdl(self):
"""Test if wsdl is cached."""
client = Client()
- response = client.get('/say_hello/')
- self.assertContains(response,
- 'location="http://testserver/say_hello/"')
- response = client.get('/say_hello/', HTTP_HOST='newtestserver')
- self.assertNotContains(response,
- 'location="http://newtestserver/say_hello/"')
+ response = client.get("/say_hello/")
+ self.assertContains(response, 'location="http://testserver/say_hello/"')
+ response = client.get("/say_hello/", HTTP_HOST="newtestserver")
+ self.assertNotContains(response, 'location="http://newtestserver/say_hello/"')
def test_not_cached_wsdl(self):
"""Test if wsdl is not cached."""
client = Client()
- response = client.get('/say_hello_not_cached/')
+ response = client.get("/say_hello_not_cached/")
self.assertContains(
- response, 'location="http://testserver/say_hello_not_cached/"')
- response = client.get('/say_hello_not_cached/',
- HTTP_HOST='newtestserver')
+ response, 'location="http://testserver/say_hello_not_cached/"'
+ )
+ response = client.get("/say_hello_not_cached/", HTTP_HOST="newtestserver")
self.assertContains(
- response, 'location="http://newtestserver/say_hello_not_cached/"')
+ response, 'location="http://newtestserver/say_hello_not_cached/"'
+ )
class ModelTestCase(TestCase):
-
"""Test mapping between django and spyne models."""
def setUp(self):
- self.client = DjangoTestClient('/api/', app)
+ self.client = DjangoTestClient("/api/", app)
def test_exclude(self):
"""Test if excluded field is not mapped."""
type_info = Container.get_flat_type_info(Container)
- self.assertIn('id', type_info)
- self.assertNotIn('excluded_field', type_info)
+ self.assertIn("id", type_info)
+ self.assertNotIn("excluded_field", type_info)
def test_pk_mapping(self):
"""Test if primary key is mapped as optional but not nillable."""
type_info = Container.get_flat_type_info(Container)
- pk_field = type_info['id']
+ pk_field = type_info["id"]
self.assertEqual(pk_field.Attributes.min_occurs, 0)
self.assertFalse(pk_field.Attributes.nullable)
def test_regex_pattern_mapping(self):
"""Test if regex pattern is mapped from django model."""
type_info = Container.get_flat_type_info(Container)
- email_field = type_info['email_field']
- self.assertEqual(email_field.__name__, 'Unicode')
+ email_field = type_info["email_field"]
+ self.assertEqual(email_field.__name__, "Unicode")
self.assertIsNotNone(email_field.Attributes.pattern)
self.assertEqual(email_field.Attributes.min_occurs, 1)
self.assertFalse(email_field.Attributes.nullable)
@@ -123,8 +119,8 @@ def test_regex_pattern_mapping(self):
def test_blank_field(self):
"""Test if blank fields are optional but not null."""
type_info = Container.get_flat_type_info(Container)
- blank_field = type_info['blank_field']
- self.assertEqual(blank_field.__name__, 'NormalizedString')
+ blank_field = type_info["blank_field"]
+ self.assertEqual(blank_field.__name__, "NormalizedString")
self.assertEqual(blank_field.Attributes.min_occurs, 0)
self.assertFalse(blank_field.Attributes.nullable)
@@ -132,13 +128,13 @@ def test_blank_as_dict(self):
"""Test if blank field is omitted in as_dict representation."""
container = Container()
container_dict = container.as_dict()
- self.assertNotIn('blank_field', container_dict)
+ self.assertNotIn("blank_field", container_dict)
def test_length_validators_field(self):
"""Test if length validators are correctly mapped."""
type_info = Container.get_flat_type_info(Container)
- length_validators_field = type_info['length_validators_field']
- self.assertEqual(length_validators_field.__name__, 'NormalizedString')
+ length_validators_field = type_info["length_validators_field"]
+ self.assertEqual(length_validators_field.__name__, "NormalizedString")
self.assertEqual(length_validators_field.Attributes.min_occurs, 1)
self.assertTrue(length_validators_field.Attributes.nullable)
self.assertEqual(length_validators_field.Attributes.min_len, 3)
@@ -148,75 +144,79 @@ def test_get_container(self):
"""Test mapping from Django model to spyne model."""
get_container = lambda: self.client.service.get_container(2)
self.assertRaises(Fault, get_container)
- container = FieldContainer.objects.create(slug_field='container')
- FieldContainer.objects.create(slug_field='container2',
- foreign_key=container,
- one_to_one_field=container,
- email_field='email@example.com',
- char_field='yo')
+ container = FieldContainer.objects.create(slug_field="container")
+ FieldContainer.objects.create(
+ slug_field="container2",
+ foreign_key=container,
+ one_to_one_field=container,
+ email_field="email@example.com",
+ char_field="yo",
+ )
c = get_container()
self.assertIsInstance(c, Container)
def test_create_container(self):
"""Test complex input to create Django model."""
- related_container = RelatedFieldContainer(id='related')
- new_container = FieldContainer(slug_field='container',
- date_field=datetime.date.today(),
- datetime_field=datetime.datetime.now(),
- email_field='email@example.com',
- time_field=datetime.time(),
- custom_foreign_key=related_container,
- custom_one_to_one_field=related_container)
- create_container = (lambda: self.client.service.create_container(
- new_container))
+ related_container = RelatedFieldContainer(id="related")
+ new_container = FieldContainer(
+ slug_field="container",
+ date_field=datetime.date.today(),
+ datetime_field=datetime.datetime.now(),
+ email_field="email@example.com",
+ time_field=datetime.time(),
+ custom_foreign_key=related_container,
+ custom_one_to_one_field=related_container,
+ )
+ create_container = lambda: self.client.service.create_container(new_container)
c = create_container()
self.assertIsInstance(c, Container)
- self.assertEqual(c.custom_one_to_one_field_id, 'related')
- self.assertEqual(c.custom_foreign_key_id, 'related')
+ self.assertEqual(c.custom_one_to_one_field_id, "related")
+ self.assertEqual(c.custom_foreign_key_id, "related")
self.assertRaises(Fault, create_container)
def test_create_container_unicode(self):
"""Test complex unicode input to create Django model."""
new_container = FieldContainer(
- char_field=u'спайн',
- text_field=u'спайн',
- slug_field='spyne',
- email_field='email@example.com',
+ char_field="спайн",
+ text_field="спайн",
+ slug_field="spyne",
+ email_field="email@example.com",
date_field=datetime.date.today(),
datetime_field=datetime.datetime.now(),
- time_field=datetime.time()
+ time_field=datetime.time(),
)
- create_container = (lambda: self.client.service.create_container(
- new_container))
+ create_container = lambda: self.client.service.create_container(new_container)
c = create_container()
self.assertIsInstance(c, Container)
self.assertRaises(Fault, create_container)
def test_optional_relation_fields(self):
"""Test if optional_relations flag makes fields optional."""
+
class UserProfile(DjangoComplexModel):
class Attributes(DjangoComplexModel.Attributes):
django_model = DjUserProfile
- self.assertFalse(UserProfile._type_info['user_id'].Attributes.nullable)
+ self.assertFalse(UserProfile._type_info["user_id"].Attributes.nullable)
class UserProfile(DjangoComplexModel):
class Attributes(DjangoComplexModel.Attributes):
django_model = DjUserProfile
django_optional_relations = True
- self.assertEqual(
- UserProfile._type_info['user_id'].Attributes.min_occurs, 0)
+ self.assertEqual(UserProfile._type_info["user_id"].Attributes.min_occurs, 0)
def test_abstract_custom_djangomodel(self):
"""Test if can create custom DjangoComplexModel."""
- @add_metaclass(DjangoComplexModelMeta)
- class OrderedDjangoComplexModel(ComplexModelBase):
+
+ class OrderedDjangoComplexModel(
+ ComplexModelBase, metaclass=DjangoComplexModelMeta
+ ):
__abstract__ = True
class Attributes(ComplexModelBase.Attributes):
- declare_order = 'declared'
+ declare_order = "declared"
class OrderedFieldContainer(OrderedDjangoComplexModel):
class Attributes(OrderedDjangoComplexModel.Attributes):
@@ -224,70 +224,69 @@ class Attributes(OrderedDjangoComplexModel.Attributes):
field_container = OrderedFieldContainer()
type_info_fields = field_container._type_info.keys()
- django_field_names = [field.get_attname() for field in
- FieldContainer._meta.fields]
+ django_field_names = [
+ field.get_attname() for field in FieldContainer._meta.fields
+ ]
# file field is not mapped
- django_field_names.remove('file_field')
+ django_field_names.remove("file_field")
# check if ordering is the same as defined in Django model
self.assertEqual(type_info_fields, django_field_names)
def test_nonabstract_custom_djangomodel(self):
"""Test if can't create non abstract custom model."""
with self.assertRaises(
- ImproperlyConfigured, msg='Can create non abstract custom model'
+ ImproperlyConfigured, msg="Can create non abstract custom model"
):
- @add_metaclass(DjangoComplexModelMeta)
- class CustomNotAbstractDjangoComplexModel(ComplexModelBase):
+
+ class CustomNotAbstractDjangoComplexModel(
+ ComplexModelBase, metaclass=DjangoComplexModelMeta
+ ):
class Attributes(ComplexModelBase.Attributes):
- declare_order = 'declared'
+ declare_order = "declared"
# in XmlSchema ^ and $ are set implicitly
-python_email_re = '^' + email_re.pattern + '$'
+python_email_re = "^" + email_re.pattern + "$"
class EmailRegexTestCase(TestCase):
-
"""Tests for email_re."""
def test_empty(self):
"""Empty string is invalid email."""
- self.assertIsNone(re.match(python_email_re, ''))
+ self.assertIsNone(re.match(python_email_re, ""))
def test_valid(self):
"""Test valid email."""
- self.assertIsNotNone(
- re.match(python_email_re, 'valid.email@example.com')
- )
+ self.assertIsNotNone(re.match(python_email_re, "valid.email@example.com"))
def test_valid_single_letter_domain(self):
"""Test valid email."""
- self.assertIsNotNone(re.match(python_email_re, 'valid.email@e.x.com'))
+ self.assertIsNotNone(re.match(python_email_re, "valid.email@e.x.com"))
def test_invalid(self):
"""Test invalid email."""
- self.assertIsNone(re.match(python_email_re, '@example.com'))
+ self.assertIsNone(re.match(python_email_re, "@example.com"))
def test_invalid_tld(self):
"""Test if email from Top Level Domain is invalid."""
- self.assertIsNone(re.match(python_email_re, 'babushka@email'))
- self.assertIsNone(re.match(python_email_re, 'babushka@domain.email-'))
+ self.assertIsNone(re.match(python_email_re, "babushka@email"))
+ self.assertIsNone(re.match(python_email_re, "babushka@domain.email-"))
class DjangoServiceTestCase(TestCase):
-
"""Tests for Django specific service."""
def test_handle_does_not_exist(self):
"""Test if Django service handles `ObjectDoesNotExist` exceptions."""
- client = DjangoTestClient('/api/', app)
- with self.assertRaisesRegexp(Fault, 'Client.FieldContainerNotFound'):
+ client = DjangoTestClient("/api/", app)
+ with self.assertRaisesRegex(Fault, "Client.FieldContainerNotFound"):
client.service.raise_does_not_exist()
def test_handle_validation_error(self):
"""Test if Django service handles `ValidationError` exceptions."""
- client = DjangoTestClient('/api/', app)
- with self.assertRaisesRegexp(Fault, 'Client.ValidationError'):
+ client = DjangoTestClient("/api/", app)
+ with self.assertRaisesRegex(Fault, "Client.ValidationError"):
client.service.raise_validation_error()
@@ -295,11 +294,11 @@ class FromUnicodeAssertionTestCase(TestCase):
def test_from_unicode_does_not_assert(self):
client = Client()
- url = '/synchro/1/'
+ url = "/synchro/1/"
msg = b"""TestModel
2015-09-23T13:54:51.796366+00:00
"""
- hdrs = {'SOAPAction': b'"sync"', 'Content-Type': 'text/xml; charset=utf-8'}
- client.post(url, msg, 'text/xml', True, **hdrs)
+ hdrs = {"SOAPAction": b'"sync"', "Content-Type": "text/xml; charset=utf-8"}
+ client.post(url, msg, "text/xml", True, **hdrs)
diff --git a/spyne/test/interop/test_httprpc.py b/spyne/test/interop/test_httprpc.py
index 4d72bc480..eba37376a 100755
--- a/spyne/test/interop/test_httprpc.py
+++ b/spyne/test/interop/test_httprpc.py
@@ -17,17 +17,14 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
-import unittest
-
import time
+import unittest
+from datetime import datetime
import pytz
-from datetime import datetime
-
from spyne.test.interop._test_soap_client_base import server_started
-from spyne.util import thread, urlencode, urlopen, Request, HTTPError
-
+from spyne.util import HTTPError, Request, thread, urlencode, urlopen
_server_started = False
@@ -38,6 +35,7 @@ def setUp(self):
from spyne.test.interop.server.httprpc_pod_basic import main, port
if not _server_started:
+
def run_server():
main()
@@ -48,10 +46,10 @@ def run_server():
_server_started = True
- self.base_url = 'http://localhost:%d' % port[0]
+ self.base_url = "http://localhost:%d" % port[0]
def test_404(self):
- url = '%s/404' % self.base_url
+ url = "%s/404" % self.base_url
try:
data = urlopen(url).read()
except HTTPError as e:
@@ -60,60 +58,64 @@ def test_404(self):
def test_413(self):
url = self.base_url
try:
- data = Request(url,("foo"*3*1024*1024))
+ data = Request(url, ("foo" * 3 * 1024 * 1024))
except HTTPError as e:
assert e.code == 413
def test_500(self):
- url = '%s/python_exception' % self.base_url
+ url = "%s/python_exception" % self.base_url
try:
data = urlopen(url).read()
except HTTPError as e:
assert e.code == 500
def test_500_2(self):
- url = '%s/soap_exception' % self.base_url
+ url = "%s/soap_exception" % self.base_url
try:
data = urlopen(url).read()
except HTTPError as e:
assert e.code == 500
def test_echo_string(self):
- url = '%s/echo_string?s=punk' % self.base_url
+ url = "%s/echo_string?s=punk" % self.base_url
data = urlopen(url).read()
- assert data == b'punk'
+ assert data == b"punk"
def test_echo_integer(self):
- url = '%s/echo_integer?i=444' % self.base_url
+ url = "%s/echo_integer?i=444" % self.base_url
data = urlopen(url).read()
- assert data == b'444'
+ assert data == b"444"
def test_echo_datetime(self):
- dt = datetime.now(pytz.utc).isoformat().encode('ascii')
- params = urlencode({
- 'dt': dt,
- })
+ dt = datetime.now(pytz.utc).isoformat().encode("ascii")
+ params = urlencode(
+ {
+ "dt": dt,
+ }
+ )
print(params)
- url = '%s/echo_datetime?%s' % (self.base_url, str(params))
+ url = "%s/echo_datetime?%s" % (self.base_url, str(params))
data = urlopen(url).read()
assert dt == data
def test_echo_datetime_tz(self):
- dt = datetime.now(pytz.utc).isoformat().encode('ascii')
- params = urlencode({
- 'dt': dt,
- })
+ dt = datetime.now(pytz.utc).isoformat().encode("ascii")
+ params = urlencode(
+ {
+ "dt": dt,
+ }
+ )
print(params)
- url = '%s/echo_datetime?%s' % (self.base_url, str(params))
+ url = "%s/echo_datetime?%s" % (self.base_url, str(params))
data = urlopen(url).read()
assert dt == data
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/interop/test_msgpackrpc_client_http.py b/spyne/test/interop/test_msgpackrpc_client_http.py
index ab39ff63d..c6a08b586 100644
--- a/spyne/test/interop/test_msgpackrpc_client_http.py
+++ b/spyne/test/interop/test_msgpackrpc_client_http.py
@@ -24,12 +24,14 @@
from spyne.test.interop.server.msgpackrpc_http_basic import msgpackrpc_application, port
from spyne.util.etreeconv import root_dict_to_etree
+
class TestSpyneHttpClient(SpyneClientTestBase, unittest.TestCase):
def setUp(self):
- SpyneClientTestBase.setUp(self, 'msgpack_rpc_http')
+ SpyneClientTestBase.setUp(self, "msgpack_rpc_http")
- self.client = HttpClient('http://localhost:%d/' % port[0],
- msgpackrpc_application)
+ self.client = HttpClient(
+ "http://localhost:%d/" % port[0], msgpackrpc_application
+ )
self.ns = "spyne.test.interop.server"
@unittest.skip("MessagePackRpc does not support header")
@@ -41,5 +43,5 @@ def test_send_out_header(self):
pass
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/interop/test_pyramid.py b/spyne/test/interop/test_pyramid.py
index 2dd3b044c..c2256a733 100755
--- a/spyne/test/interop/test_pyramid.py
+++ b/spyne/test/interop/test_pyramid.py
@@ -25,21 +25,22 @@
from pyramid.config import Configurator
from pyramid.request import Request
-from spyne.protocol.soap import Soap11
-from spyne.service import Service
-from spyne.decorator import srpc
from spyne import Application
-from spyne.model import Unicode, Integer, Iterable
+from spyne.decorator import srpc
+from spyne.model import Integer, Iterable, Unicode
+from spyne.protocol.soap import Soap11
from spyne.server.pyramid import PyramidApplication
+from spyne.service import Service
class SpyneIntegrationTest(unittest.TestCase):
"""Tests for integration of Spyne into Pyramid view callable"""
+
class HelloWorldService(Service):
@srpc(Unicode, Integer, _returns=Iterable(Unicode))
def say_hello(name, times):
for i in range(times):
- yield 'Hello, %s' % name
+ yield "Hello, %s" % name
def setUp(self):
request = testing.DummyRequest()
@@ -51,26 +52,28 @@ def tearDown(self):
def testGetWsdl(self):
"""Simple test for serving of WSDL by spyne through pyramid route"""
application = PyramidApplication(
- Application([self.HelloWorldService],
- tns='spyne.examples.hello',
- in_protocol=Soap11(validator='lxml'),
- out_protocol=Soap11()))
+ Application(
+ [self.HelloWorldService],
+ tns="spyne.examples.hello",
+ in_protocol=Soap11(validator="lxml"),
+ out_protocol=Soap11(),
+ )
+ )
- config = Configurator(settings={'debug_all': True})
- config.add_route('home', '/')
- config.add_view(application, route_name='home')
+ config = Configurator(settings={"debug_all": True})
+ config.add_route("home", "/")
+ config.add_view(application, route_name="home")
wsgi_app = validator(config.make_wsgi_app())
env = {
- 'SCRIPT_NAME': '',
- 'REQUEST_METHOD': 'GET',
- 'PATH_INFO': '/',
- 'QUERY_STRING': 'wsdl',
+ "SCRIPT_NAME": "",
+ "REQUEST_METHOD": "GET",
+ "PATH_INFO": "/",
+ "QUERY_STRING": "wsdl",
}
setup_testing_defaults(env)
request = Request(env)
resp = request.get_response(wsgi_app)
- self.assert_(resp.status.startswith("200 "))
+ self.assertTrue(resp.status.startswith("200 "))
node = etree.XML(resp.body) # will throw exception if non well formed
-
diff --git a/spyne/test/interop/test_soap_client_http.py b/spyne/test/interop/test_soap_client_http.py
index b1e88e220..6c2f48bb5 100755
--- a/spyne/test/interop/test_soap_client_http.py
+++ b/spyne/test/interop/test_soap_client_http.py
@@ -20,20 +20,22 @@
import unittest
from spyne.client.http import HttpClient
-from spyne.test.interop._test_soap_client_base import SpyneClientTestBase, \
- server_started
+from spyne.test.interop._test_soap_client_base import (
+ SpyneClientTestBase,
+ server_started,
+)
from spyne.test.interop.server.soap11.soap_http_basic import soap11_application
+
class TestSpyneHttpClient(SpyneClientTestBase, unittest.TestCase):
def setUp(self):
- SpyneClientTestBase.setUp(self, 'http')
+ SpyneClientTestBase.setUp(self, "http")
- port, = server_started.keys()
+ (port,) = server_started.keys()
- self.client = HttpClient('http://localhost:%d/' % port,
- soap11_application)
+ self.client = HttpClient("http://localhost:%d/" % port, soap11_application)
self.ns = "spyne.test.interop.server"
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/interop/test_soap_client_http_twisted.py b/spyne/test/interop/test_soap_client_http_twisted.py
index 84022e9c1..3e1783e59 100755
--- a/spyne/test/interop/test_soap_client_http_twisted.py
+++ b/spyne/test/interop/test_soap_client_http_twisted.py
@@ -18,20 +18,22 @@
#
from twisted.trial import unittest
-from spyne.test.interop._test_soap_client_base import run_server, server_started
from spyne.client.twisted import TwistedHttpClient
+from spyne.test.interop._test_soap_client_base import run_server, server_started
from spyne.test.interop.server.soap11.soap_http_basic import soap11_application
+
class TestSpyneHttpClient(unittest.TestCase):
def setUp(self):
- run_server('http')
+ run_server("http")
- port, = server_started.keys()
+ (port,) = server_started.keys()
self.ns = b"spyne.test.interop.server._service"
- self.client = TwistedHttpClient(b'http://localhost:%d/' % port,
- soap11_application)
+ self.client = TwistedHttpClient(
+ b"http://localhost:%d/" % port, soap11_application
+ )
def test_echo_boolean(self):
def eb(ret):
diff --git a/spyne/test/interop/test_soap_client_zeromq.py b/spyne/test/interop/test_soap_client_zeromq.py
index 944c2b069..282ab9c58 100755
--- a/spyne/test/interop/test_soap_client_zeromq.py
+++ b/spyne/test/interop/test_soap_client_zeromq.py
@@ -20,22 +20,22 @@
import unittest
from spyne.client.zeromq import ZeroMQClient
-
-from spyne.test.interop._test_soap_client_base import SpyneClientTestBase, \
- server_started
+from spyne.test.interop._test_soap_client_base import (
+ SpyneClientTestBase,
+ server_started,
+)
from spyne.test.interop.server.soap11.soap_http_basic import soap11_application
class TestSpyneZmqClient(SpyneClientTestBase, unittest.TestCase):
def setUp(self):
- SpyneClientTestBase.setUp(self, 'zeromq')
+ SpyneClientTestBase.setUp(self, "zeromq")
- port, = server_started.keys()
+ (port,) = server_started.keys()
- self.client = ZeroMQClient('tcp://localhost:%d' % port,
- soap11_application)
+ self.client = ZeroMQClient("tcp://localhost:%d" % port, soap11_application)
self.ns = "spyne.test.interop.server._service"
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/interop/test_suds.py b/spyne/test/interop/test_suds.py
index f77f89ce3..0a0dee9a5 100755
--- a/spyne/test/interop/test_suds.py
+++ b/spyne/test/interop/test_suds.py
@@ -18,23 +18,23 @@
#
import logging
-suds_logger = logging.getLogger('suds')
+
+suds_logger = logging.getLogger("suds")
suds_logger.setLevel(logging.INFO)
import unittest
-
+from base64 import b64decode, b64encode
from datetime import datetime
-from base64 import b64encode, b64decode
-from suds.sax.parser import Parser
+from suds import WebFault
from suds.client import Client
from suds.plugin import MessagePlugin
-from suds import WebFault
-
-from spyne.util import six
+from suds.sax.parser import Parser
-from spyne.test.interop._test_soap_client_base import SpyneClientTestBase, \
- server_started
+from spyne.test.interop._test_soap_client_base import (
+ SpyneClientTestBase,
+ server_started,
+)
class LastReceivedPlugin(MessagePlugin):
@@ -45,12 +45,15 @@ def received(self, context):
class TestSuds(SpyneClientTestBase, unittest.TestCase):
def setUp(self):
- SpyneClientTestBase.setUp(self, 'http')
+ from spyne.test.interop.server.soap11.soap_http_basic import port as _port
- port, = server_started.keys()
+ SpyneClientTestBase.setUp(self, "http")
- self.client = Client("http://localhost:%d/?wsdl" % port, cache=None,
- plugins=[LastReceivedPlugin()])
+ self.client = Client(
+ "http://localhost:%d/?wsdl" % _port[0],
+ cache=None,
+ plugins=[LastReceivedPlugin()],
+ )
self.ns = "spyne.test.interop.server"
def test_echo_datetime(self):
@@ -120,8 +123,7 @@ def test_bytearray(self):
assert val == b64decode(ret)
def test_validation(self):
- non_nillable_class = self.client.factory.create(
- "{hunk.sunk}NonNillableClass")
+ non_nillable_class = self.client.factory.create("{hunk.sunk}NonNillableClass")
non_nillable_class.i = 6
non_nillable_class.s = None
@@ -133,13 +135,13 @@ def test_validation(self):
raise Exception("must fail")
def test_echo_integer_array(self):
- ia = self.client.factory.create('integerArray')
+ ia = self.client.factory.create("integerArray")
ia.integer.extend([1, 2, 3, 4, 5])
self.client.service.echo_integer_array(ia)
def test_echo_in_header(self):
- in_header = self.client.factory.create('InHeader')
- in_header.s = 'a'
+ in_header = self.client.factory.create("InHeader")
+ in_header.s = "a"
in_header.i = 3
self.client.set_options(soapheaders=in_header)
@@ -152,13 +154,14 @@ def test_echo_in_header(self):
self.assertEqual(in_header.i, ret.i)
def test_echo_in_complex_header(self):
- in_header = self.client.factory.create('InHeader')
- in_header.s = 'a'
+ in_header = self.client.factory.create("InHeader")
+ in_header.s = "a"
in_header.i = 3
- in_trace_header = self.client.factory.create('InTraceHeader')
- in_trace_header.client = 'suds'
- in_trace_header.callDate = datetime(year=2000, month=1, day=1, hour=0,
- minute=0, second=0, microsecond=0)
+ in_trace_header = self.client.factory.create("InTraceHeader")
+ in_trace_header.client = "suds"
+ in_trace_header.callDate = datetime(
+ year=2000, month=1, day=1, hour=0, minute=0, second=0, microsecond=0
+ )
self.client.set_options(soapheaders=(in_header, in_trace_header))
ret = self.client.service.echo_in_complex_header()
@@ -172,7 +175,7 @@ def test_echo_in_complex_header(self):
self.assertEqual(in_trace_header.callDate, ret[1].callDate)
def test_send_out_header(self):
- out_header = self.client.factory.create('OutHeader')
+ out_header = self.client.factory.create("OutHeader")
out_header.dt = datetime(year=2000, month=1, day=1)
out_header.f = 3.141592653
@@ -183,14 +186,16 @@ def test_send_out_header(self):
self.assertEqual(ret.f, out_header.f)
def test_send_out_complex_header(self):
- out_header = self.client.factory.create('OutHeader')
+ out_header = self.client.factory.create("OutHeader")
out_header.dt = datetime(year=2000, month=1, day=1)
out_header.f = 3.141592653
- out_trace_header = self.client.factory.create('OutTraceHeader')
- out_trace_header.receiptDate = datetime(year=2000, month=1, day=1,
- hour=1, minute=1, second=1, microsecond=1)
- out_trace_header.returnDate = datetime(year=2000, month=1, day=1,
- hour=1, minute=1, second=1, microsecond=100)
+ out_trace_header = self.client.factory.create("OutTraceHeader")
+ out_trace_header.receiptDate = datetime(
+ year=2000, month=1, day=1, hour=1, minute=1, second=1, microsecond=1
+ )
+ out_trace_header.returnDate = datetime(
+ year=2000, month=1, day=1, hour=1, minute=1, second=1, microsecond=100
+ )
ret = self.client.service.send_out_complex_header()
@@ -202,19 +207,36 @@ def test_send_out_complex_header(self):
self.assertEqual(ret[1].returnDate, out_trace_header.returnDate)
# Control the reply soap header (in an unelegant way but this is the
# only way with suds)
- soapheaders = self.client.options.plugins[0].reply.getChild("Envelope").getChild("Header")
- soap_out_header = soapheaders.getChild('OutHeader')
- self.assertEqual('T'.join((out_header.dt.date().isoformat(),
- out_header.dt.time().isoformat())),
- soap_out_header.getChild('dt').getText())
- self.assertEqual(six.text_type(out_header.f), soap_out_header.getChild('f').getText())
- soap_out_trace_header = soapheaders.getChild('OutTraceHeader')
- self.assertEqual('T'.join((out_trace_header.receiptDate.date().isoformat(),
- out_trace_header.receiptDate.time().isoformat())),
- soap_out_trace_header.getChild('receiptDate').getText())
- self.assertEqual('T'.join((out_trace_header.returnDate.date().isoformat(),
- out_trace_header.returnDate.time().isoformat())),
- soap_out_trace_header.getChild('returnDate').getText())
+ soapheaders = (
+ self.client.options.plugins[0].reply.getChild("Envelope").getChild("Header")
+ )
+ soap_out_header = soapheaders.getChild("OutHeader")
+ self.assertEqual(
+ "T".join(
+ (out_header.dt.date().isoformat(), out_header.dt.time().isoformat())
+ ),
+ soap_out_header.getChild("dt").getText(),
+ )
+ self.assertEqual(str(out_header.f), soap_out_header.getChild("f").getText())
+ soap_out_trace_header = soapheaders.getChild("OutTraceHeader")
+ self.assertEqual(
+ "T".join(
+ (
+ out_trace_header.receiptDate.date().isoformat(),
+ out_trace_header.receiptDate.time().isoformat(),
+ )
+ ),
+ soap_out_trace_header.getChild("receiptDate").getText(),
+ )
+ self.assertEqual(
+ "T".join(
+ (
+ out_trace_header.returnDate.date().isoformat(),
+ out_trace_header.returnDate.time().isoformat(),
+ )
+ ),
+ soap_out_trace_header.getChild("returnDate").getText(),
+ )
def test_echo_string(self):
test_string = "OK"
@@ -225,24 +247,17 @@ def test_echo_string(self):
def __get_xml_test_val(self):
return {
"test_sub": {
- "test_subsub1": {
- "test_subsubsub1": ["subsubsub1 value"]
- },
+ "test_subsub1": {"test_subsubsub1": ["subsubsub1 value"]},
"test_subsub2": ["subsub2 value 1", "subsub2 value 2"],
"test_subsub3": [
- {
- "test_subsub3sub1": ["subsub3sub1 value"]
- },
- {
- "test_subsub3sub2": ["subsub3sub2 value"]
- },
+ {"test_subsub3sub1": ["subsub3sub1 value"]},
+ {"test_subsub3sub2": ["subsub3sub2 value"]},
],
"test_subsub4": [],
"test_subsub5": ["x"],
}
}
-
def test_echo_simple_class(self):
val = self.client.factory.create("{spyne.test.interop.server}SimpleClass")
@@ -255,10 +270,14 @@ def test_echo_simple_class(self):
assert ret.s == val.s
def test_echo_class_with_self_reference(self):
- val = self.client.factory.create("{spyne.test.interop.server}ClassWithSelfReference")
+ val = self.client.factory.create(
+ "{spyne.test.interop.server}ClassWithSelfReference"
+ )
val.i = 45
- val.sr = self.client.factory.create("{spyne.test.interop.server}ClassWithSelfReference")
+ val.sr = self.client.factory.create(
+ "{spyne.test.interop.server}ClassWithSelfReference"
+ )
val.sr.i = 50
val.sr.sr = None
@@ -268,7 +287,7 @@ def test_echo_class_with_self_reference(self):
assert ret.sr.i == val.sr.i
def test_echo_nested_class(self):
- val = self.client.factory.create("{punk.tunk}NestedClass");
+ val = self.client.factory.create("{punk.tunk}NestedClass")
val.i = 45
val.s = "asd"
@@ -276,17 +295,23 @@ def test_echo_nested_class(self):
val.ai = self.client.factory.create("integerArray")
val.ai.integer.extend([1, 2, 3, 45, 5, 3, 2, 1, 4])
- val.simple = self.client.factory.create("{spyne.test.interop.server}SimpleClassArray")
+ val.simple = self.client.factory.create(
+ "{spyne.test.interop.server}SimpleClassArray"
+ )
- val.simple.SimpleClass.append(self.client.factory.create("{spyne.test.interop.server}SimpleClass"))
- val.simple.SimpleClass.append(self.client.factory.create("{spyne.test.interop.server}SimpleClass"))
+ val.simple.SimpleClass.append(
+ self.client.factory.create("{spyne.test.interop.server}SimpleClass")
+ )
+ val.simple.SimpleClass.append(
+ self.client.factory.create("{spyne.test.interop.server}SimpleClass")
+ )
val.simple.SimpleClass[0].i = 45
val.simple.SimpleClass[0].s = "asd"
val.simple.SimpleClass[1].i = 12
val.simple.SimpleClass[1].s = "qwe"
- val.other = self.client.factory.create("{spyne.test.interop.server}OtherClass");
+ val.other = self.client.factory.create("{spyne.test.interop.server}OtherClass")
val.other.dt = datetime.now()
val.other.d = 123.456
val.other.b = True
@@ -302,8 +327,9 @@ def test_huge_number(self):
self.assertEqual(self.client.service.huge_number(), 2 ** int(1e4))
def test_long_string(self):
- self.assertEqual(self.client.service.long_string(),
- ('0123456789abcdef' * 16384))
+ self.assertEqual(
+ self.client.service.long_string(), ("0123456789abcdef" * 16384)
+ )
def test_empty(self):
self.client.service.test_empty()
@@ -315,22 +341,28 @@ def test_echo_extension_class(self):
val.s = "asd"
val.f = 12.34
- val.simple = self.client.factory.create("{spyne.test.interop.server}SimpleClassArray")
+ val.simple = self.client.factory.create(
+ "{spyne.test.interop.server}SimpleClassArray"
+ )
- val.simple.SimpleClass.append(self.client.factory.create("{spyne.test.interop.server}SimpleClass"))
- val.simple.SimpleClass.append(self.client.factory.create("{spyne.test.interop.server}SimpleClass"))
+ val.simple.SimpleClass.append(
+ self.client.factory.create("{spyne.test.interop.server}SimpleClass")
+ )
+ val.simple.SimpleClass.append(
+ self.client.factory.create("{spyne.test.interop.server}SimpleClass")
+ )
val.simple.SimpleClass[0].i = 45
val.simple.SimpleClass[0].s = "asd"
val.simple.SimpleClass[1].i = 12
val.simple.SimpleClass[1].s = "qwe"
- val.other = self.client.factory.create("{spyne.test.interop.server}OtherClass");
+ val.other = self.client.factory.create("{spyne.test.interop.server}OtherClass")
val.other.dt = datetime.now()
val.other.d = 123.456
val.other.b = True
- val.p = self.client.factory.create("{hunk.sunk}NonNillableClass");
+ val.p = self.client.factory.create("{hunk.sunk}NonNillableClass")
val.p.dt = datetime(2010, 6, 2)
val.p.i = 123
val.p.s = "punk"
@@ -348,7 +380,6 @@ def test_echo_extension_class(self):
self.assertEqual(ret.other.dt, val.other.dt)
self.assertEqual(ret.p.s, val.p.s)
-
def test_python_exception(self):
try:
self.client.service.python_exception()
@@ -381,18 +412,18 @@ def test_return_invalid_data(self):
def test_custom_messages(self):
ret = self.client.service.custom_messages("test")
- assert ret == 'test'
+ assert ret == "test"
def test_echo_simple_bare(self):
ret = self.client.service.echo_simple_bare("test")
- assert ret == 'test'
+ assert ret == "test"
#
# This test is disabled because suds does not create the right request
# object. Opening the first tag below is wrong.
#
- #
#
#
- #
+ #
#
# The right request looks like this:
#
@@ -416,13 +447,13 @@ def test_echo_simple_bare(self):
#
#
def _test_echo_complex_bare(self):
- val = ['abc','def']
- ia = self.client.factory.create('stringArray')
+ val = ["abc", "def"]
+ ia = self.client.factory.create("stringArray")
ia.string.extend(val)
ret = self.client.service.echo_complex_bare(ia)
assert ret == val
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/interop/test_zeep.py b/spyne/test/interop/test_zeep.py
index fa5486003..a1ccaf325 100755
--- a/spyne/test/interop/test_zeep.py
+++ b/spyne/test/interop/test_zeep.py
@@ -18,33 +18,30 @@
#
import logging
-
-zeep_logger = logging.getLogger('zeep')
+zeep_logger = logging.getLogger("zeep")
zeep_logger.setLevel(logging.INFO)
import unittest
-
from datetime import datetime
-from base64 import b64encode, b64decode
-
-from spyne.test.interop._test_soap_client_base import server_started
-from spyne.util import six
from zeep import Client
-from zeep.transports import Transport
from zeep.exceptions import Error as ZeepError
+from zeep.transports import Transport
+
+from spyne.test.interop._test_soap_client_base import server_started
class TestZeep(unittest.TestCase):
def setUp(self):
from spyne.test.interop._test_soap_client_base import run_server
- run_server('http')
+ from spyne.test.interop.server.soap11.soap_http_basic import port as _port
- port, = server_started.keys()
+ run_server("http")
transport = Transport(cache=False)
- self.client = Client("http://localhost:%d/?wsdl" % port,
- transport=transport)
+ self.client = Client(
+ "http://localhost:%d/?wsdl" % _port[0], transport=transport
+ )
self.ns = "spyne.test.interop.server"
def get_inst(self, what):
@@ -102,7 +99,7 @@ def test_echo_boolean(self):
self.assertEqual(val, ret)
def test_enum(self):
- val = self.client.get_type("{%s}DaysOfWeekEnum" % self.ns)('Monday')
+ val = self.client.get_type("{%s}DaysOfWeekEnum" % self.ns)("Monday")
ret = self.client.service.echo_enum(val)
@@ -127,18 +124,20 @@ def test_validation(self):
raise Exception("must fail")
def test_echo_integer_array(self):
- ia = self.client.get_type('{%s}integerArray' % self.ns)()
+ ia = self.client.get_type("{%s}integerArray" % self.ns)()
ia.integer.extend([1, 2, 3, 4, 5])
self.client.service.echo_integer_array(ia)
def test_echo_in_header(self):
- in_header = self.client.get_type('{%s}InHeader' % self.ns)()
- in_header.s = 'a'
+ in_header = self.client.get_type("{%s}InHeader" % self.ns)()
+ in_header.s = "a"
in_header.i = 3
- ret = self.client.service.echo_in_header(_soapheaders={
- 'InHeader': in_header,
- })
+ ret = self.client.service.echo_in_header(
+ _soapheaders={
+ "InHeader": in_header,
+ }
+ )
print(ret)
@@ -147,18 +146,18 @@ def test_echo_in_header(self):
self.assertEqual(in_header.i, out_header.i)
def test_echo_in_complex_header(self):
- in_header = self.client.get_type('{%s}InHeader' % self.ns)()
- in_header.s = 'a'
+ in_header = self.client.get_type("{%s}InHeader" % self.ns)()
+ in_header.s = "a"
in_header.i = 3
- in_trace_header = self.client.get_type('{%s}InTraceHeader' % self.ns)()
- in_trace_header.client = 'suds'
- in_trace_header.callDate = datetime(year=2000, month=1, day=1, hour=0,
- minute=0, second=0, microsecond=0)
+ in_trace_header = self.client.get_type("{%s}InTraceHeader" % self.ns)()
+ in_trace_header.client = "suds"
+ in_trace_header.callDate = datetime(
+ year=2000, month=1, day=1, hour=0, minute=0, second=0, microsecond=0
+ )
- ret = self.client.service.echo_in_complex_header(_soapheaders={
- 'InHeader': in_header,
- 'InTraceHeader': in_trace_header
- })
+ ret = self.client.service.echo_in_complex_header(
+ _soapheaders={"InHeader": in_header, "InTraceHeader": in_trace_header}
+ )
print(ret)
@@ -171,7 +170,7 @@ def test_echo_in_complex_header(self):
self.assertEqual(in_trace_header.callDate, out_trace_header.callDate)
def test_send_out_header(self):
- out_header = self.client.get_type('{%s}OutHeader' % self.ns)()
+ out_header = self.client.get_type("{%s}OutHeader" % self.ns)()
out_header.dt = datetime(year=2000, month=1, day=1)
out_header.f = 3.141592653
@@ -181,21 +180,27 @@ def test_send_out_header(self):
self.assertEqual(ret.header.OutHeader.f, out_header.f)
def test_send_out_complex_header(self):
- out_header = self.client.get_type('{%s}OutHeader' % self.ns)()
+ out_header = self.client.get_type("{%s}OutHeader" % self.ns)()
out_header.dt = datetime(year=2000, month=1, day=1)
out_header.f = 3.141592653
- out_trace_header = self.client.get_type('{%s}OutTraceHeader' % self.ns)()
- out_trace_header.receiptDate = datetime(year=2000, month=1, day=1,
- hour=1, minute=1, second=1, microsecond=1)
- out_trace_header.returnDate = datetime(year=2000, month=1, day=1,
- hour=1, minute=1, second=1, microsecond=100)
+ out_trace_header = self.client.get_type("{%s}OutTraceHeader" % self.ns)()
+ out_trace_header.receiptDate = datetime(
+ year=2000, month=1, day=1, hour=1, minute=1, second=1, microsecond=1
+ )
+ out_trace_header.returnDate = datetime(
+ year=2000, month=1, day=1, hour=1, minute=1, second=1, microsecond=100
+ )
ret = self.client.service.send_out_complex_header()
self.assertEqual(ret.header.OutHeader.dt, out_header.dt)
self.assertEqual(ret.header.OutHeader.f, out_header.f)
- self.assertEqual(ret.header.OutTraceHeader.receiptDate, out_trace_header.receiptDate)
- self.assertEqual(ret.header.OutTraceHeader.returnDate, out_trace_header.returnDate)
+ self.assertEqual(
+ ret.header.OutTraceHeader.receiptDate, out_trace_header.receiptDate
+ )
+ self.assertEqual(
+ ret.header.OutTraceHeader.returnDate, out_trace_header.returnDate
+ )
def test_echo_string(self):
test_string = "OK"
@@ -206,24 +211,17 @@ def test_echo_string(self):
def __get_xml_test_val(self):
return {
"test_sub": {
- "test_subsub1": {
- "test_subsubsub1": ["subsubsub1 value"]
- },
+ "test_subsub1": {"test_subsubsub1": ["subsubsub1 value"]},
"test_subsub2": ["subsub2 value 1", "subsub2 value 2"],
"test_subsub3": [
- {
- "test_subsub3sub1": ["subsub3sub1 value"]
- },
- {
- "test_subsub3sub2": ["subsub3sub2 value"]
- },
+ {"test_subsub3sub1": ["subsub3sub1 value"]},
+ {"test_subsub3sub2": ["subsub3sub2 value"]},
],
"test_subsub4": [],
"test_subsub5": ["x"],
}
}
-
def test_echo_simple_class(self):
val = self.client.get_type("{%s}SimpleClass" % self.ns)()
@@ -259,8 +257,12 @@ def test_echo_nested_class(self):
val.simple = self.client.get_type("{%s}SimpleClassArray" % self.ns)()
- val.simple.SimpleClass.append(self.client.get_type("{%s}SimpleClass" % self.ns)())
- val.simple.SimpleClass.append(self.client.get_type("{%s}SimpleClass" % self.ns)())
+ val.simple.SimpleClass.append(
+ self.client.get_type("{%s}SimpleClass" % self.ns)()
+ )
+ val.simple.SimpleClass.append(
+ self.client.get_type("{%s}SimpleClass" % self.ns)()
+ )
val.simple.SimpleClass[0].i = 45
val.simple.SimpleClass[0].s = "asd"
@@ -284,8 +286,9 @@ def test_huge_number(self):
self.assertEqual(self.client.service.huge_number(), 2 ** int(1e4))
def test_long_string(self):
- self.assertEqual(self.client.service.long_string(),
- ('0123456789abcdef' * 16384))
+ self.assertEqual(
+ self.client.service.long_string(), ("0123456789abcdef" * 16384)
+ )
def test_empty(self):
self.client.service.test_empty()
@@ -299,8 +302,12 @@ def test_echo_extension_class(self):
val.simple = self.client.get_type("{%s}SimpleClassArray" % self.ns)()
- val.simple.SimpleClass.append(self.client.get_type("{%s}SimpleClass" % self.ns)())
- val.simple.SimpleClass.append(self.client.get_type("{%s}SimpleClass" % self.ns)())
+ val.simple.SimpleClass.append(
+ self.client.get_type("{%s}SimpleClass" % self.ns)()
+ )
+ val.simple.SimpleClass.append(
+ self.client.get_type("{%s}SimpleClass" % self.ns)()
+ )
val.simple.SimpleClass[0].i = 45
val.simple.SimpleClass[0].s = "asd"
@@ -330,7 +337,6 @@ def test_echo_extension_class(self):
self.assertEqual(ret.other.dt, val.other.dt)
self.assertEqual(ret.p.s, val.p.s)
-
def test_python_exception(self):
try:
self.client.service.python_exception()
@@ -363,18 +369,19 @@ def test_return_invalid_data(self):
def test_custom_messages(self):
ret = self.client.service.custom_messages("test")
- assert ret == 'test'
+ assert ret == "test"
def test_echo_simple_bare(self):
ret = self.client.service.echo_simple_bare("test")
- assert ret == 'test'
+ assert ret == "test"
def test_echo_complex_bare(self):
- val = ['abc','def']
+ val = ["abc", "def"]
ret = self.client.service.echo_complex_bare(val)
assert ret == val
-if __name__ == '__main__':
+
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/interop/test_wsi.py b/spyne/test/interop/wsi_analyzer.py
similarity index 65%
rename from spyne/test/interop/test_wsi.py
rename to spyne/test/interop/wsi_analyzer.py
index cb0aefeba..b8556fbd4 100755
--- a/spyne/test/interop/test_wsi.py
+++ b/spyne/test/interop/wsi_analyzer.py
@@ -12,14 +12,15 @@
import os
import string
+
from lxml import etree
-CONFIG_FILE = 'config.xml'
-SPYNE_TEST_NS = 'spyne.test.interop.server'
-SPYNE_TEST_PORT = 'Application'
-SPYNE_REPORT_FILE = 'wsi-report-spyne.xml'
+CONFIG_FILE = "config.xml"
+SPYNE_TEST_NS = "spyne.test.interop.server"
+SPYNE_TEST_PORT = "Application"
+SPYNE_REPORT_FILE = "wsi-report-spyne.xml"
-WSI_ANALYZER_CONFIG_TEMPLATE=string.Template("""
+WSI_ANALYZER_CONFIG_TEMPLATE = string.Template("""
@@ -66,33 +67,33 @@
""")
-#This must be changed to point to the physical root of the wsi-installation
+# This must be changed to point to the physical root of the wsi-installation
WSI_HOME_TAG = "WSI_HOME"
WSI_HOME_VAL = "wsi-test-tools"
WSI_JAVA_HOME_TAG = "WSI_JAVA_HOME"
-WSI_JAVA_HOME_VAL = WSI_HOME_VAL+"/java"
+WSI_JAVA_HOME_VAL = WSI_HOME_VAL + "/java"
WSI_JAVA_OPTS_TAG = "WSI_JAVA_OPTS"
WSI_JAVA_OPTS_VAL = " -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser"
-WSI_TEST_ASSERTIONS_FILE = WSI_HOME_VAL+"/common/profiles/SSBP10_BP11_TAD.xml"
-WSI_STYLESHEET_FILE = WSI_HOME_VAL+"/common/xsl/report.xsl"
+WSI_TEST_ASSERTIONS_FILE = WSI_HOME_VAL + "/common/profiles/SSBP10_BP11_TAD.xml"
+WSI_STYLESHEET_FILE = WSI_HOME_VAL + "/common/xsl/report.xsl"
WSI_EXECUTION_COMMAND = "java ${WSI_JAVA_OPTS} -Dwsi.home=${WSI_HOME} -cp ${WSI_CP}\
org.wsi.test.analyzer.BasicProfileAnalyzer -config "
-WSIClasspath=[
- WSI_JAVA_HOME_VAL+"/lib/wsi-test-tools.jar",
- WSI_JAVA_HOME_VAL+"/lib",
- WSI_JAVA_HOME_VAL+"/lib/xercesImpl.jar",
- WSI_JAVA_HOME_VAL+"/lib/xmlParserAPIs.jar",
- WSI_JAVA_HOME_VAL+"/lib/wsdl4j.jar",
- WSI_JAVA_HOME_VAL+"/lib/uddi4j.jar",
- WSI_JAVA_HOME_VAL+"/lib/axis.jar",
- WSI_JAVA_HOME_VAL+"/lib/jaxrpc.jar",
- WSI_JAVA_HOME_VAL+"/lib/saaj.jar",
- WSI_JAVA_HOME_VAL+"/lib/commons-discovery.jar",
- WSI_JAVA_HOME_VAL+"/lib/commons-logging.jar"
+WSIClasspath = [
+ WSI_JAVA_HOME_VAL + "/lib/wsi-test-tools.jar",
+ WSI_JAVA_HOME_VAL + "/lib",
+ WSI_JAVA_HOME_VAL + "/lib/xercesImpl.jar",
+ WSI_JAVA_HOME_VAL + "/lib/xmlParserAPIs.jar",
+ WSI_JAVA_HOME_VAL + "/lib/wsdl4j.jar",
+ WSI_JAVA_HOME_VAL + "/lib/uddi4j.jar",
+ WSI_JAVA_HOME_VAL + "/lib/axis.jar",
+ WSI_JAVA_HOME_VAL + "/lib/jaxrpc.jar",
+ WSI_JAVA_HOME_VAL + "/lib/saaj.jar",
+ WSI_JAVA_HOME_VAL + "/lib/commons-discovery.jar",
+ WSI_JAVA_HOME_VAL + "/lib/commons-logging.jar",
]
WSI_CLASSPATH_TAG = "WSI_CP"
-WSI_CLASSPATH_VAL = ':'.join(WSIClasspath)
+WSI_CLASSPATH_VAL = ":".join(WSIClasspath)
def configure_env():
@@ -101,24 +102,28 @@ def configure_env():
os.environ[WSI_JAVA_OPTS_TAG] = WSI_JAVA_OPTS_VAL
os.environ[WSI_CLASSPATH_TAG] = WSI_CLASSPATH_VAL
+
def create_config(wsdl_uri, config_file):
- print(("Creating config for wsdl at %s ...\n" %wsdl_uri))
+ print(("Creating config for wsdl at %s ...\n" % wsdl_uri))
# extract target elements
- service = 'ValidatingApplication'
- port = 'ValidatingApplication'
+ service = "ValidatingApplication"
+ port = "ValidatingApplication"
# for wsdl service declarations:
# create config(service, port)
- vars = {'REPORT_FILE':SPYNE_REPORT_FILE,
- 'STYLESHEET_FILE':WSI_STYLESHEET_FILE,
- 'ASSERTIONS_FILE':WSI_TEST_ASSERTIONS_FILE,
- 'WSDL_NAMESPACE':SPYNE_TEST_NS,
- 'PORT_NAME':SPYNE_TEST_PORT,
- 'WSDL_URI':wsdl_uri}
+ vars = {
+ "REPORT_FILE": SPYNE_REPORT_FILE,
+ "STYLESHEET_FILE": WSI_STYLESHEET_FILE,
+ "ASSERTIONS_FILE": WSI_TEST_ASSERTIONS_FILE,
+ "WSDL_NAMESPACE": SPYNE_TEST_NS,
+ "PORT_NAME": SPYNE_TEST_PORT,
+ "WSDL_URI": wsdl_uri,
+ }
config = WSI_ANALYZER_CONFIG_TEMPLATE.substitute(vars)
- f = open(config_file, 'w')
+ f = open(config_file, "w")
f.write(config)
f.close()
+
def analyze_wsdl(config_file):
# execute ws-i tests
# don't execute Analyzer.sh directly since it needs bash
@@ -126,15 +131,15 @@ def analyze_wsdl(config_file):
# parse result
e = etree.parse(SPYNE_REPORT_FILE).getroot()
- summary = etree.ETXPath('{%s}summary' %e.nsmap['wsi-report'])(e)
+ summary = etree.ETXPath("{%s}summary" % e.nsmap["wsi-report"])(e)
if summary:
# retrieve overall result of the test
- result = summary[0].get('result')
- if result == 'failed':
- outs = etree.ETXPath('{%s}artifact' %(e.nsmap['wsi-report'],))(e)
+ result = summary[0].get("result")
+ if result == "failed":
+ outs = etree.ETXPath("{%s}artifact" % (e.nsmap["wsi-report"],))(e)
# filter for the object describing the wsdl test
- desc = [o for o in outs if o.get('type') == 'description'][0]
+ desc = [o for o in outs if o.get("type") == "description"][0]
# loop over every group test
for entry in desc.iterchildren():
@@ -142,20 +147,25 @@ def analyze_wsdl(config_file):
for test in entry.iterchildren():
# simply print the error if there is one
# an html can be generated using files in wsi-test-tools/common/xsl
- if test.get('result') == 'failed':
- fail_msg = etree.ETXPath('{%s}failureMessage' %e.nsmap['wsi-report'])(test)
- fail_det = etree.ETXPath('{%s}failureDetail' %e.nsmap['wsi-report'])(test)
+ if test.get("result") == "failed":
+ fail_msg = etree.ETXPath(
+ "{%s}failureMessage" % e.nsmap["wsi-report"]
+ )(test)
+ fail_det = etree.ETXPath(
+ "{%s}failureDetail" % e.nsmap["wsi-report"]
+ )(test)
if fail_msg:
- print(('\nFAILURE in test %s\n' %test.get('id')))
+ print(("\nFAILURE in test %s\n" % test.get("id")))
print((fail_msg[0].text))
if fail_det:
- print('\nFAILURE MSG\n')
+ print("\nFAILURE MSG\n")
print((fail_det[0].text))
+
from spyne.test.interop._test_soap_client_base import run_server
-if __name__ == '__main__':
- run_server('http')
+if __name__ == "__main__":
+ run_server("http")
configure_env()
- create_config('http://localhost:9754/?wsdl', CONFIG_FILE)
+ create_config("http://localhost:9754/?wsdl", CONFIG_FILE)
analyze_wsdl(CONFIG_FILE)
diff --git a/spyne/test/model/__init__.py b/spyne/test/model/__init__.py
index 7b899d595..d55474f4e 100644
--- a/spyne/test/model/__init__.py
+++ b/spyne/test/model/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
diff --git a/spyne/test/model/test_binary.py b/spyne/test/model/test_binary.py
index 06a4841c9..78217101a 100755
--- a/spyne/test/model/test_binary.py
+++ b/spyne/test/model/test_binary.py
@@ -18,23 +18,23 @@
#
import unittest
+
from lxml import etree
-from spyne.protocol.soap import Soap11
-from spyne.model.binary import ByteArray
-from spyne.model.binary import _bytes_join
import spyne.const.xml
+from spyne.model.binary import ByteArray, _bytes_join
+from spyne.protocol.soap import Soap11
ns_xsd = spyne.const.xml.NS_XSD
-ns_test = 'test_namespace'
+ns_test = "test_namespace"
class TestBinary(unittest.TestCase):
def setUp(self):
- self.data = bytes(bytearray(range(0xff)))
+ self.data = bytes(bytearray(range(0xFF)))
def test_data(self):
- element = etree.Element('test')
+ element = etree.Element("test")
Soap11().to_parent(None, ByteArray, [self.data], element, ns_test)
print(etree.tostring(element, pretty_print=True))
element = element[0]
@@ -42,5 +42,6 @@ def test_data(self):
a2 = Soap11().from_element(None, ByteArray, element)
self.assertEqual(self.data, _bytes_join(a2))
-if __name__ == '__main__':
+
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/model/test_complex.py b/spyne/test/model/test_complex.py
index 0bc56e0d0..70fd77363 100755
--- a/spyne/test/model/test_complex.py
+++ b/spyne/test/model/test_complex.py
@@ -19,35 +19,45 @@
from __future__ import print_function
-import pytz
import datetime
import unittest
-
+from base64 import b64encode
+from decimal import Decimal as D
from pprint import pprint
+import pytz
from lxml import etree
-from base64 import b64encode
-from decimal import Decimal as D
-
-from spyne import Application, rpc, mrpc, Service, ByteArray, Array, \
- ComplexModel, SelfReference, XmlData, XmlAttribute, Unicode, DateTime, \
- Float, Integer, String
+from spyne import (
+ Application,
+ Array,
+ ByteArray,
+ ComplexModel,
+ DateTime,
+ Float,
+ Integer,
+ SelfReference,
+ Service,
+ String,
+ Unicode,
+ XmlAttribute,
+ XmlData,
+ mrpc,
+ rpc,
+)
from spyne.const import xml
from spyne.error import ResourceNotFoundError
from spyne.interface import Interface
from spyne.interface.wsdl import Wsdl11
-from spyne.model.addtl import TimeSegment, DateSegment, DateTimeSegment
+from spyne.model.addtl import DateSegment, DateTimeSegment, TimeSegment
from spyne.protocol import ProtocolBase
-from spyne.protocol.soap import Soap11
-from spyne.server.null import NullServer
-
from spyne.protocol.dictdoc import SimpleDictDocument
+from spyne.protocol.soap import Soap11
from spyne.protocol.xml import XmlDocument
-
+from spyne.server.null import NullServer
from spyne.test import FakeApp
-ns_test = 'test_namespace'
+ns_test = "test_namespace"
class Address(ComplexModel):
@@ -58,6 +68,7 @@ class Address(ComplexModel):
lattitude = Float
longitude = Float
+
Address.resolve_namespace(Address, __name__)
@@ -68,6 +79,7 @@ class Person(ComplexModel):
addresses = Array(Address)
titles = Array(String)
+
Person.resolve_namespace(Person, __name__)
@@ -75,24 +87,29 @@ class Employee(Person):
employee_id = Integer
salary = Float
+
Employee.resolve_namespace(Employee, __name__)
+
class Level2(ComplexModel):
arg1 = String
arg2 = Float
+
Level2.resolve_namespace(Level2, __name__)
class Level3(ComplexModel):
arg1 = Integer
+
Level3.resolve_namespace(Level3, __name__)
class Level4(ComplexModel):
arg1 = String
+
Level4.resolve_namespace(Level4, __name__)
@@ -101,6 +118,7 @@ class Level1(ComplexModel):
level3 = Array(Level3)
level4 = Array(Level4)
+
Level1.resolve_namespace(Level1, __name__)
@@ -110,11 +128,11 @@ class C(ComplexModel):
i = Integer(voa=True)
try:
- C().i = 'a'
+ C().i = "a"
except ValueError:
pass
else:
- raise Exception('must fail with ValueError')
+ raise Exception("must fail with ValueError")
def test_validate_on_assignment_success(self):
class C(ComplexModel):
@@ -130,19 +148,19 @@ class C(ComplexModel):
def test_simple_class(self):
a = Address()
- a.street = '123 happy way'
- a.city = 'badtown'
+ a.street = "123 happy way"
+ a.city = "badtown"
a.zip = 32
a.lattitude = 4.3
a.longitude = 88.0
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, Address, a, element, ns_test)
element = element[0]
self.assertEqual(5, len(element.getchildren()))
a.since = datetime.datetime(year=2011, month=12, day=31, tzinfo=pytz.utc)
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, Address, a, element, ns_test)
element = element[0]
self.assertEqual(6, len(element.getchildren()))
@@ -156,9 +174,9 @@ def test_simple_class(self):
self.assertEqual(a.longitude, r.longitude)
self.assertEqual(a.since, r.since)
- def test_nested_class(self): # FIXME: this test is incomplete
+ def test_nested_class(self): # FIXME: this test is incomplete
p = Person()
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, Person, p, element, ns_test)
element = element[0]
@@ -169,7 +187,7 @@ def test_nested_class(self): # FIXME: this test is incomplete
def test_class_array(self):
peeps = []
- names = ['bob', 'jim', 'peabody', 'mumblesleeves']
+ names = ["bob", "jim", "peabody", "mumblesleeves"]
dob = datetime.datetime(1979, 1, 1, tzinfo=pytz.utc)
for name in names:
a = Person()
@@ -181,7 +199,7 @@ def test_class_array(self):
type = Array(Person)
type.resolve_namespace(type, __name__)
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, type, peeps, element, ns_test)
element = element[0]
@@ -195,7 +213,7 @@ def test_class_array(self):
def test_class_nested_array(self):
peeps = []
- names = ['bob', 'jim', 'peabody', 'mumblesleves']
+ names = ["bob", "jim", "peabody", "mumblesleves"]
for name in names:
a = Person()
@@ -206,14 +224,14 @@ def test_class_nested_array(self):
for i in range(0, 25):
addr = Address()
- addr.street = '555 downtown'
- addr.city = 'funkytown'
+ addr.street = "555 downtown"
+ addr.city = "funkytown"
a.addresses.append(addr)
peeps.append(a)
arr = Array(Person)
arr.resolve_namespace(arr, __name__)
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, arr, peeps, element, ns_test)
element = element[0]
@@ -223,12 +241,12 @@ def test_class_nested_array(self):
for peep in peeps2:
self.assertEqual(27, peep.age)
self.assertEqual(25, len(peep.addresses))
- self.assertEqual('funkytown', peep.addresses[18].city)
+ self.assertEqual("funkytown", peep.addresses[18].city)
def test_complex_class(self):
l = Level1()
l.level2 = Level2()
- l.level2.arg1 = 'abcd'
+ l.level2.arg1 = "abcd"
l.level2.arg2 = 1.444
l.level3 = []
l.level4 = []
@@ -243,7 +261,7 @@ def test_complex_class(self):
a.arg1 = str(i)
l.level4.append(a)
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, Level1, l, element, ns_test)
element = element[0]
l1 = XmlDocument().from_element(None, Level1, element)
@@ -255,12 +273,12 @@ def test_complex_class(self):
class X(ComplexModel):
- __namespace__ = 'tns'
- x = Integer(nillable=True, max_occurs='unbounded')
+ __namespace__ = "tns"
+ x = Integer(nillable=True, max_occurs="unbounded")
class Y(X):
- __namespace__ = 'tns'
+ __namespace__ = "tns"
y = Integer
@@ -268,8 +286,8 @@ class TestIncompleteInput(unittest.TestCase):
def test_x(self):
x = X()
x.x = [1, 2]
- element = etree.Element('test')
- XmlDocument().to_parent(None, X, x, element, 'tns')
+ element = etree.Element("test")
+ XmlDocument().to_parent(None, X, x, element, "tns")
msg = element[0]
r = XmlDocument().from_element(None, X, msg)
self.assertEqual(r.x, [1, 2])
@@ -277,8 +295,8 @@ def test_x(self):
def test_y_fromxml(self):
x = X()
x.x = [1, 2]
- element = etree.Element('test')
- XmlDocument().to_parent(None, X, x, element, 'tns')
+ element = etree.Element("test")
+ XmlDocument().to_parent(None, X, x, element, "tns")
msg = element[0]
r = XmlDocument().from_element(None, Y, msg)
self.assertEqual(r.x, [1, 2])
@@ -287,16 +305,13 @@ def test_y_toxml(self):
y = Y()
y.x = [1, 2]
y.y = 38
- element = etree.Element('test')
- XmlDocument().to_parent(None, Y, y, element, 'tns')
+ element = etree.Element("test")
+ XmlDocument().to_parent(None, Y, y, element, "tns")
msg = element[0]
r = XmlDocument().from_element(None, Y, msg)
def test_serialization_instance_on_subclass(self):
- test_values = {
- 'x': [1, 2],
- 'y': 38
- }
+ test_values = {"x": [1, 2], "y": 38}
instance = Y.get_serialization_instance(test_values)
self.assertEqual(instance.x, [1, 2])
@@ -317,34 +332,35 @@ class EncExtractXs(ComplexModel):
enc_idn = Integer(nillable=False, min_occurs=1, max_occurs=1, max_len=18)
hist_idn = Integer(nillable=False, min_occurs=1, max_occurs=1, max_len=18)
+
class TestComplex(unittest.TestCase):
def test_array_type_name(self):
- assert Array(String, type_name='punk').__type_name__ == 'punk'
+ assert Array(String, type_name="punk").__type_name__ == "punk"
def test_ctor_kwargs(self):
class Category(ComplexModel):
id = Integer(min_occurs=1, max_occurs=1, nillable=False)
children = Array(Unicode)
- v = Category(id=5, children=['a','b'])
+ v = Category(id=5, children=["a", "b"])
assert v.id == 5
- assert v.children == ['a', 'b']
+ assert v.children == ["a", "b"]
def test_ctor_args(self):
class Category(ComplexModel):
id = XmlData(Integer(min_occurs=1, max_occurs=1, nillable=False))
children = Array(Unicode)
- v = Category(id=5, children=['a','b'])
+ v = Category(id=5, children=["a", "b"])
assert v.id == 5
- assert v.children == ['a', 'b']
+ assert v.children == ["a", "b"]
- v = Category(5, children=['a','b'])
+ v = Category(5, children=["a", "b"])
assert v.id == 5
- assert v.children == ['a', 'b']
+ assert v.children == ["a", "b"]
def test_ctor_args_2(self):
class Category(ComplexModel):
@@ -353,10 +369,10 @@ class Category(ComplexModel):
class BetterCategory(Category):
sub_category = Unicode
- v = BetterCategory(children=['a','b'], sub_category='aaa')
+ v = BetterCategory(children=["a", "b"], sub_category="aaa")
- assert v.children == ['a', 'b']
- assert v.sub_category == 'aaa'
+ assert v.children == ["a", "b"]
+ assert v.sub_category == "aaa"
def test_flat_type_info(self):
class A(ComplexModel):
@@ -365,8 +381,8 @@ class A(ComplexModel):
class B(A):
s = String
- assert 's' in B.get_flat_type_info(B)
- assert 'i' in B.get_flat_type_info(B)
+ assert "s" in B.get_flat_type_info(B)
+ assert "i" in B.get_flat_type_info(B)
def test_flat_type_info_attr(self):
class A(ComplexModel):
@@ -377,12 +393,12 @@ class B(A):
s = String
sa = XmlAttribute(String)
- assert 's' in B.get_flat_type_info(B)
- assert 'i' in B.get_flat_type_info(B)
- assert 'sa' in B.get_flat_type_info(B)
- assert 'ia' in B.get_flat_type_info(B)
- assert 'sa' in B.get_flat_type_info(B).attrs
- assert 'ia' in B.get_flat_type_info(B).attrs
+ assert "s" in B.get_flat_type_info(B)
+ assert "i" in B.get_flat_type_info(B)
+ assert "sa" in B.get_flat_type_info(B)
+ assert "ia" in B.get_flat_type_info(B)
+ assert "sa" in B.get_flat_type_info(B).attrs
+ assert "ia" in B.get_flat_type_info(B).attrs
class TestXmlAttribute(unittest.TestCase):
@@ -390,7 +406,7 @@ def assertIsNotNone(self, obj, msg=None):
"""Stolen from Python 2.7 stdlib."""
if obj is None:
- standardMsg = 'unexpectedly None'
+ standardMsg = "unexpectedly None"
self.fail(self._formatMessage(msg, standardMsg))
def test_add_to_schema(self):
@@ -400,58 +416,60 @@ class CM(ComplexModel):
a = XmlAttribute(String)
app = FakeApp()
- app.tns = 'tns'
+ app.tns = "tns"
CM.resolve_namespace(CM, app.tns)
interface = Interface(app)
interface.add_class(CM)
wsdl = Wsdl11(interface)
- wsdl.build_interface_document('http://a-aaaa.com')
+ wsdl.build_interface_document("http://a-aaaa.com")
pref = CM.get_namespace_prefix(interface)
type_def = wsdl.get_schema_info(pref).types[CM.get_type_name()]
- attribute_def = type_def.find(xml.XSD('attribute'))
+ attribute_def = type_def.find(xml.XSD("attribute"))
print(etree.tostring(type_def, pretty_print=True))
self.assertIsNotNone(attribute_def)
- self.assertEqual(attribute_def.get('name'), 'a')
- self.assertEqual(attribute_def.get('type'), CM.a.type.get_type_name_ns(interface))
+ self.assertEqual(attribute_def.get("name"), "a")
+ self.assertEqual(
+ attribute_def.get("type"), CM.a.type.get_type_name_ns(interface)
+ )
def test_b64_non_attribute(self):
class PacketNonAttribute(ComplexModel):
- __namespace__ = 'myns'
+ __namespace__ = "myns"
Data = ByteArray
- test_string = b'yo test data'
+ test_string = b"yo test data"
b64string = b64encode(test_string)
gg = PacketNonAttribute(Data=[test_string])
- element = etree.Element('test')
+ element = etree.Element("test")
Soap11().to_parent(None, PacketNonAttribute, gg, element, gg.get_namespace())
element = element[0]
- #print etree.tostring(element, pretty_print=True)
- data = element.find('{%s}Data' % gg.get_namespace()).text
- self.assertEqual(data, b64string.decode('ascii'))
+ # print etree.tostring(element, pretty_print=True)
+ data = element.find("{%s}Data" % gg.get_namespace()).text
+ self.assertEqual(data, b64string.decode("ascii"))
s1 = Soap11().from_element(None, PacketNonAttribute, element)
assert s1.Data[0] == test_string
def test_b64_attribute(self):
class PacketAttribute(ComplexModel):
- __namespace__ = 'myns'
- Data = XmlAttribute(ByteArray, use='required')
+ __namespace__ = "myns"
+ Data = XmlAttribute(ByteArray, use="required")
- test_string = b'yo test data'
+ test_string = b"yo test data"
b64string = b64encode(test_string)
gg = PacketAttribute(Data=[test_string])
- element = etree.Element('test')
+ element = etree.Element("test")
Soap11().to_parent(None, PacketAttribute, gg, element, gg.get_namespace())
element = element[0]
print(etree.tostring(element, pretty_print=True))
print(element.attrib)
- self.assertEqual(element.attrib['Data'], b64string.decode('ascii'))
+ self.assertEqual(element.attrib["Data"], b64string.decode("ascii"))
s1 = Soap11().from_element(None, PacketAttribute, element)
assert s1.Data[0] == test_string
@@ -459,11 +477,13 @@ class PacketAttribute(ComplexModel):
def test_customized_type(self):
class SomeClass(ComplexModel):
a = XmlAttribute(Integer(ge=4))
+
class SomeService(Service):
@rpc(SomeClass)
def some_call(ctx, some_class):
pass
- app = Application([SomeService], 'some_tns')
+
+ app = Application([SomeService], "some_tns")
class TestSimpleTypeRestrictions(unittest.TestCase):
@@ -481,20 +501,20 @@ class CCM(ComplexModel):
pprint(sti)
assert "i" in sti
- assert sti["i"].path == ('i',)
+ assert sti["i"].path == ("i",)
assert sti["i"].type is Integer
assert sti["s"].parent is CCM
assert "s" in sti
- assert sti["s"].path == ('s',)
+ assert sti["s"].path == ("s",)
assert sti["s"].type is String
assert sti["s"].parent is CCM
assert "c.i" in sti
- assert sti["c.i"].path == ('c','i')
+ assert sti["c.i"].path == ("c", "i")
assert sti["c.i"].type is Integer
assert sti["c.i"].parent is CM
assert "c.s" in sti
- assert sti["c.s"].path == ('c','s')
+ assert sti["c.s"].path == ("c", "s")
assert sti["c.s"].type is String
assert sti["c.s"].parent is CM
@@ -508,12 +528,13 @@ class CCM(ComplexModel):
c_i = Float
try:
- CCM.get_simple_type_info(CCM, hier_delim='_')
+ CCM.get_simple_type_info(CCM, hier_delim="_")
except ValueError:
pass
else:
raise Exception("must fail")
+
class TestFlatDict(unittest.TestCase):
def test_basic(self):
class CM(ComplexModel):
@@ -525,46 +546,46 @@ class CCM(ComplexModel):
i = Integer
s = String
- val = CCM(i=5, s='a', c=CM(i=7, s='b'))
+ val = CCM(i=5, s="a", c=CM(i=7, s="b"))
d = SimpleDictDocument().object_to_simple_dict(CCM, val)
- assert d['i'] == 5
- assert d['s'] == 'a'
- assert d['c.i'] == 7
- assert d['c.s'] == 'b'
+ assert d["i"] == 5
+ assert d["s"] == "a"
+ assert d["c.i"] == 7
+ assert d["c.s"] == "b"
assert len(d) == 4
def test_sub_name_ser(self):
class CM(ComplexModel):
- integer = Integer(sub_name='i')
- string = String(sub_name='s')
+ integer = Integer(sub_name="i")
+ string = String(sub_name="s")
- val = CM(integer=7, string='b')
+ val = CM(integer=7, string="b")
d = SimpleDictDocument().object_to_simple_dict(CM, val)
pprint(d)
- assert d['i'] == 7
- assert d['s'] == 'b'
+ assert d["i"] == 7
+ assert d["s"] == "b"
assert len(d) == 2
def test_sub_name_deser(self):
class CM(ComplexModel):
- integer = Integer(sub_name='i')
- string = String(sub_name='s')
+ integer = Integer(sub_name="i")
+ string = String(sub_name="s")
- d = {'i': [7], 's': ['b']}
+ d = {"i": [7], "s": ["b"]}
val = SimpleDictDocument().simple_dict_to_object(None, d, CM)
pprint(d)
assert val.integer == 7
- assert val.string == 'b'
+ assert val.string == "b"
def test_array_not_none(self):
class CM(ComplexModel):
@@ -574,15 +595,15 @@ class CM(ComplexModel):
class CCM(ComplexModel):
c = Array(CM)
- val = CCM(c=[CM(i=i, s='b'*(i+1)) for i in range(2)])
+ val = CCM(c=[CM(i=i, s="b" * (i + 1)) for i in range(2)])
d = SimpleDictDocument().object_to_simple_dict(CCM, val)
print(d)
- assert d['c[0].i'] == 0
- assert d['c[0].s'] == 'b'
- assert d['c[1].i'] == 1
- assert d['c[1].s'] == 'bb'
+ assert d["c[0].i"] == 0
+ assert d["c[0].s"] == "b"
+ assert d["c[1].i"] == 1
+ assert d["c[1].s"] == "bb"
assert len(d) == 4
@@ -613,8 +634,8 @@ class CCM(ComplexModel):
d = SimpleDictDocument().object_to_simple_dict(CCM, val)
pprint(d)
- assert d['c[0].i'] == [0, 1]
- assert d['c[1].i'] == [0, 1, 2]
+ assert d["c[0].i"] == [0, 1]
+ assert d["c[1].i"] == [0, 1, 2]
assert len(d) == 2
@@ -622,7 +643,7 @@ def test_array_nonwrapped(self):
i = Array(Integer, wrapped=False)
assert issubclass(i, Integer), i
- assert i.Attributes.max_occurs == D('infinity')
+ assert i.Attributes.max_occurs == D("infinity")
class TestSelfRefence(unittest.TestCase):
@@ -630,7 +651,7 @@ def test_canonical_case(self):
class TestSelfReference(ComplexModel):
self_reference = SelfReference
- c = TestSelfReference._type_info['self_reference']
+ c = TestSelfReference._type_info["self_reference"]
c = c.__orig__ or c
assert c is TestSelfReference
@@ -640,31 +661,35 @@ class SoapService(Service):
def view_categories(ctx):
pass
- Application([SoapService], 'service.soap')
+ Application([SoapService], "service.soap")
def test_self_referential_array_workaround(self):
from spyne.util.dictdoc import get_object_as_dict
+
class Category(ComplexModel):
id = Integer(min_occurs=1, max_occurs=1, nillable=False)
- Category._type_info['children'] = Array(Category)
+ Category._type_info["children"] = Array(Category)
parent = Category()
parent.children = [Category(id=0), Category(id=1)]
d = get_object_as_dict(parent, Category)
pprint(d)
- assert d['children'][0]['id'] == 0
- assert d['children'][1]['id'] == 1
+ assert d["children"][0]["id"] == 0
+ assert d["children"][1]["id"] == 1
class SoapService(Service):
@rpc(_returns=Category)
def view_categories(ctx):
pass
- Application([SoapService], 'service.soap',
- in_protocol=ProtocolBase(),
- out_protocol=ProtocolBase())
+ Application(
+ [SoapService],
+ "service.soap",
+ in_protocol=ProtocolBase(),
+ out_protocol=ProtocolBase(),
+ )
def test_canonical_array(self):
class Category(ComplexModel):
@@ -674,7 +699,7 @@ class Category(ComplexModel):
parent = Category()
parent.children = [Category(id=1), Category(id=2)]
- sr, = Category._type_info['children']._type_info.values()
+ (sr,) = Category._type_info["children"]._type_info.values()
assert issubclass(sr, Category)
@@ -687,7 +712,7 @@ def put(self, ctx):
methods = SomeComplexModel.Attributes.methods
print(methods)
- assert 'put' in methods
+ assert "put" in methods
def test_simple_customize(self):
class SomeComplexModel(ComplexModel):
@@ -695,34 +720,36 @@ class SomeComplexModel(ComplexModel):
def put(self, ctx):
return "PUNK!!!"
- methods = SomeComplexModel.customize(zart='zurt').Attributes.methods
+ methods = SomeComplexModel.customize(zart="zurt").Attributes.methods
print(methods)
- assert 'put' in methods
+ assert "put" in methods
def test_simple_with_fields(self):
class SomeComplexModel(ComplexModel):
a = Integer
+
@mrpc()
def put(self, ctx):
return "PUNK!!!"
methods = SomeComplexModel.Attributes.methods
print(methods)
- assert 'put' in methods
+ assert "put" in methods
def test_simple_with_explicit_fields(self):
class SomeComplexModel(ComplexModel):
- _type_info = [('a', Integer)]
+ _type_info = [("a", Integer)]
+
@mrpc()
def put(self, ctx):
return "PUNK!!!"
methods = SomeComplexModel.Attributes.methods
print(methods)
- assert 'put' in methods
+ assert "put" in methods
def test_native_call(self):
- v = 'whatever'
+ v = "whatever"
class SomeComplexModel(ComplexModel):
@mrpc()
@@ -739,16 +766,16 @@ def member_method(self, ctx):
methods = SomeComplexModel.Attributes.methods
print(methods)
- assert 'member_method' in methods
+ assert "member_method" in methods
class SomeService(Service):
@rpc(_returns=SomeComplexModel)
def service_method(ctx):
return SomeComplexModel()
- app = Application([SomeService], 'some_ns')
+ app = Application([SomeService], "some_ns")
- mmm = __name__ + '.SomeComplexModel.member_method'
+ mmm = __name__ + ".SomeComplexModel.member_method"
assert mmm in app.interface.method_id_map
def test_interface_mult(self):
@@ -759,25 +786,26 @@ def member_method(self, ctx):
methods = SomeComplexModel.Attributes.methods
print(methods)
- assert 'member_method' in methods
+ assert "member_method" in methods
class SomeService(Service):
@rpc(_returns=SomeComplexModel)
def service_method(ctx):
return SomeComplexModel()
- @rpc(_returns=SomeComplexModel.customize(type_name='zon'))
+ @rpc(_returns=SomeComplexModel.customize(type_name="zon"))
def service_method_2(ctx):
return SomeComplexModel()
- app = Application([SomeService], 'some_ns')
+ app = Application([SomeService], "some_ns")
- mmm = __name__ + '.SomeComplexModel.member_method'
+ mmm = __name__ + ".SomeComplexModel.member_method"
assert mmm in app.interface.method_id_map
def test_remote_call_error(self):
from spyne import mrpc
- v = 'deger'
+
+ v = "deger"
class SomeComplexModel(ComplexModel):
@mrpc(_returns=SelfReference)
@@ -789,15 +817,17 @@ class SomeService(Service):
def get(ctx):
return SomeComplexModel()
- null = NullServer(Application([SomeService], tns='some_tns'))
+ null = NullServer(Application([SomeService], tns="some_tns"))
try:
null.service.put()
except ResourceNotFoundError:
pass
else:
- raise Exception("Must fail with: \"Requested resource "
- "'{spyne.test.model.test_complex}SomeComplexModel' not found\"")
+ raise Exception(
+ 'Must fail with: "Requested resource '
+ "'{spyne.test.model.test_complex}SomeComplexModel' not found\""
+ )
def test_signature(self):
class SomeComplexModel(ComplexModel):
@@ -808,7 +838,10 @@ def member_method(self, ctx):
methods = SomeComplexModel.Attributes.methods
# we use __orig__ because implicit classes are .customize(validate_freq=False)'d
- assert methods['member_method'].in_message._type_info[0].__orig__ is SomeComplexModel
+ assert (
+ methods["member_method"].in_message._type_info[0].__orig__
+ is SomeComplexModel
+ )
def test_self_reference(self):
from spyne import mrpc
@@ -819,13 +852,14 @@ def method(self, ctx):
pass
methods = SomeComplexModel.Attributes.methods
- assert methods['method'].out_message._type_info[0] is SomeComplexModel
+ assert methods["method"].out_message._type_info[0] is SomeComplexModel
def test_remote_call_success(self):
from spyne import mrpc
class SomeComplexModel(ComplexModel):
i = Integer
+
@mrpc(_returns=SelfReference)
def echo(self, ctx):
return self
@@ -835,55 +869,63 @@ class SomeService(Service):
def get(ctx):
return SomeComplexModel()
- null = NullServer(Application([SomeService], tns='some_tns'))
+ null = NullServer(Application([SomeService], tns="some_tns"))
v = SomeComplexModel(i=5)
- assert null.service['SomeComplexModel.echo'](v) is v
+ assert null.service["SomeComplexModel.echo"](v) is v
def test_order(self):
class CM(ComplexModel):
- _type_info = [
- ('a', Integer),
- ('c', Integer(order=0))
- ]
+ _type_info = [("a", Integer), ("c", Integer(order=0))]
- assert CM._type_info.keys() == ['c', 'a']
+ assert CM._type_info.keys() == ["c", "a"]
class TestDoc(unittest.TestCase):
def test_parent_doc(self):
class SomeComplexModel(ComplexModel):
"""Some docstring"""
+
some_field = Unicode
+
class Annotations(ComplexModel.Annotations):
__use_parent_doc__ = True
+
assert "Some docstring" == SomeComplexModel.get_documentation()
def test_annotation(self):
class SomeComplexModel(ComplexModel):
"""Some docstring"""
+
class Annotations(ComplexModel.Annotations):
doc = "Some annotations"
some_field = Unicode
+
assert "Some annotations" == SomeComplexModel.get_documentation()
def test_no_parent_doc(self):
class SomeComplexModel(ComplexModel):
"""Some docstring"""
+
class Annotations(ComplexModel.Annotations):
__use_parent_doc__ = False
some_field = Unicode
+
assert "" == SomeComplexModel.get_documentation()
def test_parent_doc_customize(self):
"""Check that we keep the documentation when we use customize"""
+
class SomeComplexModel(ComplexModel):
"""Some docstring"""
+
some_field = Unicode
+
class Annotations(ComplexModel.Annotations):
__use_parent_doc__ = True
+
assert "Some docstring" == SomeComplexModel.customize().get_documentation()
@@ -913,7 +955,7 @@ def test_noop(self):
class A(ComplexModel):
s = Unicode
- assert A.get_flat_type_info(A)['s'].Attributes.max_len == D('inf')
+ assert A.get_flat_type_info(A)["s"].Attributes.max_len == D("inf")
def test_cust_simple(self):
# simple types are different from complex ones for __extends__ handling.
@@ -940,15 +982,9 @@ def test_cust_complex(self):
class A(ComplexModel):
s = Unicode
- A2 = A.customize(
- child_attrs=dict(
- s=dict(
- max_len=10
- )
- )
- )
+ A2 = A.customize(child_attrs=dict(s=dict(max_len=10)))
- assert A2.get_flat_type_info(A2)['s'].Attributes.max_len == 10
+ assert A2.get_flat_type_info(A2)["s"].Attributes.max_len == 10
def test_cust_base_class(self):
class A(ComplexModel):
@@ -965,7 +1001,7 @@ class B(A):
),
)
- assert B2.get_flat_type_info(B2)['s'].Attributes.max_len == 10
+ assert B2.get_flat_type_info(B2)["s"].Attributes.max_len == 10
def test_cust_again_base_class(self):
class A(ComplexModel):
@@ -973,8 +1009,10 @@ class A(ComplexModel):
A2 = A.customize()
try:
+
class B(A2):
i = Integer
+
except AssertionError:
pass
else:
@@ -990,9 +1028,9 @@ def test_cust_array(self):
def test_cust_array_again(self):
A = Array(Unicode)
- A = A.customize(foo='bar')
+ A = A.customize(foo="bar")
- assert A.Attributes.foo == 'bar'
+ assert A.Attributes.foo == "bar"
assert A.__orig__ is Array
assert A.__extends__ is None
assert issubclass(A, Array)
@@ -1006,7 +1044,7 @@ def test_cust_array_serializer(self):
),
)
- serializer, = A._type_info.values()
+ (serializer,) = A._type_info.values()
assert serializer.Attributes.max_len == 10
assert serializer.__orig__ is Unicode
@@ -1014,6 +1052,7 @@ def test_cust_array_serializer(self):
def test_cust_sub_array(self):
"""vanilla class is passed as base"""
+
class A(ComplexModel):
s = Array(Unicode)
@@ -1029,7 +1068,7 @@ class A(ComplexModel):
A2 = A.customize(**d)
- ser, = A2._type_info['s']._type_info.values()
+ (ser,) = A2._type_info["s"]._type_info.values()
assert ser.Attributes.max_len == 10
class B(A):
@@ -1038,7 +1077,7 @@ class B(A):
B2 = B.customize(**d)
b2_fti = B2.get_flat_type_info(B2)
- ser, = b2_fti['s']._type_info.values()
+ (ser,) = b2_fti["s"]._type_info.values()
assert ser.Attributes.max_len == 10
@@ -1051,10 +1090,10 @@ class B(A):
d = DateTime
B2 = B.customize(child_attrs=dict(s=dict(max_len=10)))
- assert B2.get_flat_type_info(B2)['s'].Attributes.max_len == 10
+ assert B2.get_flat_type_info(B2)["s"].Attributes.max_len == 10
B3 = B2.customize(child_attrs=dict(d=dict(dt_format="%y")))
- assert B3.get_flat_type_info(B3)['s'].Attributes.max_len == 10
+ assert B3.get_flat_type_info(B3)["s"].Attributes.max_len == 10
def test_cust_all(self):
class A(ComplexModel):
@@ -1065,8 +1104,8 @@ class B(A):
d = DateTime
B2 = B.customize(child_attrs_all=dict(max_len=10))
- assert B2.get_flat_type_info(B2)['s'].Attributes.max_len == 10
- assert B2.get_flat_type_info(B2)['i'].Attributes.max_len == 10
+ assert B2.get_flat_type_info(B2)["s"].Attributes.max_len == 10
+ assert B2.get_flat_type_info(B2)["i"].Attributes.max_len == 10
def test_cust_noexc(self):
class A(ComplexModel):
@@ -1077,10 +1116,9 @@ class B(A):
d = DateTime
B2 = B.customize(child_attrs_noexc=dict(s=dict(max_len=10)))
- assert B2.get_flat_type_info(B2)['s'].Attributes.max_len == 10
- assert B2.get_flat_type_info(B2)['s'].Attributes.exc == False
- assert B2.get_flat_type_info(B2)['i'].Attributes.exc == True
-
+ assert B2.get_flat_type_info(B2)["s"].Attributes.max_len == 10
+ assert B2.get_flat_type_info(B2)["s"].Attributes.exc == False
+ assert B2.get_flat_type_info(B2)["i"].Attributes.exc == True
def test_complex_type_name_clashes(self):
class TestComplexModel(ComplexModel):
@@ -1103,16 +1141,18 @@ def test2(ctx, obj):
pass
try:
- Application([TestService], 'tns')
+ Application([TestService], "tns")
except Exception as e:
print(e)
else:
- raise Exception("must fail with: "
+ raise Exception(
+ "must fail with: "
"ValueError: classes "
- " "
- "and "
- " "
- "have conflicting names.")
+ " "
+ "and "
+ " "
+ "have conflicting names."
+ )
class TestAdditional(unittest.TestCase):
@@ -1133,14 +1173,15 @@ def test_date_segment(self):
assert data.end_inclusive == False
def test_datetime_segment(self):
- data = DateTimeSegment.from_string("]2016-03-03T10:20:30.405060,"
- "2016-05-07T00:01:02.030405]")
+ data = DateTimeSegment.from_string(
+ "]2016-03-03T10:20:30.405060," "2016-05-07T00:01:02.030405]"
+ )
assert data.start_inclusive == False
assert data.start == datetime.datetime(2016, 3, 3, 10, 20, 30, 405060)
- assert data.end == datetime.datetime(2016, 5, 7, 0, 1, 2, 30405)
+ assert data.end == datetime.datetime(2016, 5, 7, 0, 1, 2, 30405)
assert data.end_inclusive == True
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/model/test_enum.py b/spyne/test/model/test_enum.py
index 7d8fd4f5b..3aadbd410 100755
--- a/spyne/test/model/test_enum.py
+++ b/spyne/test/model/test_enum.py
@@ -18,46 +18,43 @@
#
import unittest
-
from pprint import pprint
+from lxml import etree
+
from spyne.application import Application
from spyne.const.xml import XSD
+from spyne.decorator import rpc
from spyne.interface.wsdl.wsdl11 import Wsdl11
-from spyne.model.complex import Array
-from spyne.model.complex import ComplexModel
-from spyne.protocol.xml import XmlDocument
+from spyne.model.complex import Array, ComplexModel
+from spyne.model.enum import Enum
from spyne.protocol.soap.soap11 import Soap11
-
+from spyne.protocol.xml import XmlDocument
from spyne.server.wsgi import WsgiApplication
from spyne.service import Service
-from spyne.decorator import rpc
-
-from spyne.model.enum import Enum
-
-from lxml import etree
vals = [
- 'Monday',
- 'Tuesday',
- 'Wednesday',
- 'Thursday',
- 'Friday',
- 'Saturday',
- 'Sunday',
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ "Sunday",
]
DaysOfWeekEnum = Enum(
- 'Monday',
- 'Tuesday',
- 'Wednesday',
- 'Thursday',
- 'Friday',
- 'Saturday',
- 'Sunday',
- type_name = 'DaysOfWeekEnum',
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ "Sunday",
+ type_name="DaysOfWeekEnum",
)
+
class SomeService(Service):
@rpc(DaysOfWeekEnum, _returns=DaysOfWeekEnum)
def get_the_day(self, day):
@@ -70,33 +67,36 @@ class SomeClass(ComplexModel):
class TestEnum(unittest.TestCase):
def setUp(self):
- self.app = Application([SomeService], 'tns',
- in_protocol=Soap11(), out_protocol=Soap11())
- self.app.transport = 'test'
+ self.app = Application(
+ [SomeService], "tns", in_protocol=Soap11(), out_protocol=Soap11()
+ )
+ self.app.transport = "test"
self.server = WsgiApplication(self.app)
self.wsdl = Wsdl11(self.app.interface)
- self.wsdl.build_interface_document('prot://url')
+ self.wsdl.build_interface_document("prot://url")
def test_wsdl(self):
wsdl = self.wsdl.get_interface_document()
elt = etree.fromstring(wsdl)
- simple_type = elt.xpath('//xs:simpleType', namespaces=self.app.interface.nsmap)[0]
+ simple_type = elt.xpath("//xs:simpleType", namespaces=self.app.interface.nsmap)[
+ 0
+ ]
print((etree.tostring(elt, pretty_print=True)))
print(simple_type)
- self.assertEqual(simple_type.attrib['name'], 'DaysOfWeekEnum')
+ self.assertEqual(simple_type.attrib["name"], "DaysOfWeekEnum")
self.assertEqual(simple_type[0].tag, XSD("restriction"))
- self.assertEqual([e.attrib['value'] for e in simple_type[0]], vals)
+ self.assertEqual([e.attrib["value"] for e in simple_type[0]], vals)
def test_serialize(self):
mo = DaysOfWeekEnum.Monday
print((repr(mo)))
- elt = etree.Element('test')
- XmlDocument().to_parent(None, DaysOfWeekEnum, mo, elt, 'test_namespace')
+ elt = etree.Element("test")
+ XmlDocument().to_parent(None, DaysOfWeekEnum, mo, elt, "test_namespace")
elt = elt[0]
ret = XmlDocument().from_element(None, DaysOfWeekEnum, elt)
@@ -104,31 +104,30 @@ def test_serialize(self):
def test_serialize_complex_array(self):
days = [
- DaysOfWeekEnum.Monday,
- DaysOfWeekEnum.Tuesday,
- DaysOfWeekEnum.Wednesday,
- DaysOfWeekEnum.Thursday,
- DaysOfWeekEnum.Friday,
- DaysOfWeekEnum.Saturday,
- DaysOfWeekEnum.Sunday,
- ]
+ DaysOfWeekEnum.Monday,
+ DaysOfWeekEnum.Tuesday,
+ DaysOfWeekEnum.Wednesday,
+ DaysOfWeekEnum.Thursday,
+ DaysOfWeekEnum.Friday,
+ DaysOfWeekEnum.Saturday,
+ DaysOfWeekEnum.Sunday,
+ ]
days_xml = [
- ('{tns}DaysOfWeekEnum', 'Monday'),
- ('{tns}DaysOfWeekEnum', 'Tuesday'),
- ('{tns}DaysOfWeekEnum', 'Wednesday'),
- ('{tns}DaysOfWeekEnum', 'Thursday'),
- ('{tns}DaysOfWeekEnum', 'Friday'),
- ('{tns}DaysOfWeekEnum', 'Saturday'),
- ('{tns}DaysOfWeekEnum', 'Sunday'),
+ ("{tns}DaysOfWeekEnum", "Monday"),
+ ("{tns}DaysOfWeekEnum", "Tuesday"),
+ ("{tns}DaysOfWeekEnum", "Wednesday"),
+ ("{tns}DaysOfWeekEnum", "Thursday"),
+ ("{tns}DaysOfWeekEnum", "Friday"),
+ ("{tns}DaysOfWeekEnum", "Saturday"),
+ ("{tns}DaysOfWeekEnum", "Sunday"),
]
DaysOfWeekEnumArray = Array(DaysOfWeekEnum)
- DaysOfWeekEnumArray.__namespace__ = 'tns'
+ DaysOfWeekEnumArray.__namespace__ = "tns"
- elt = etree.Element('test')
- XmlDocument().to_parent(None, DaysOfWeekEnumArray, days,
- elt, 'test_namespace')
+ elt = etree.Element("test")
+ XmlDocument().to_parent(None, DaysOfWeekEnumArray, days, elt, "test_namespace")
elt = elt[0]
ret = XmlDocument().from_element(None, Array(DaysOfWeekEnum), elt)
@@ -137,11 +136,16 @@ def test_serialize_complex_array(self):
print((etree.tostring(elt, pretty_print=True)))
pprint(self.app.interface.nsmap)
- assert days_xml == [ (e.tag, e.text) for e in
- elt.xpath('//tns:DaysOfWeekEnum', namespaces=self.app.interface.nsmap)]
+ assert days_xml == [
+ (e.tag, e.text)
+ for e in elt.xpath(
+ "//tns:DaysOfWeekEnum", namespaces=self.app.interface.nsmap
+ )
+ ]
def test_serialize_simple_array(self):
- t = SomeClass(days=[
+ t = SomeClass(
+ days=[
DaysOfWeekEnum.Monday,
DaysOfWeekEnum.Tuesday,
DaysOfWeekEnum.Wednesday,
@@ -149,12 +153,13 @@ def test_serialize_simple_array(self):
DaysOfWeekEnum.Friday,
DaysOfWeekEnum.Saturday,
DaysOfWeekEnum.Sunday,
- ])
+ ]
+ )
- SomeClass.resolve_namespace(SomeClass, 'tns')
+ SomeClass.resolve_namespace(SomeClass, "tns")
- elt = etree.Element('test')
- XmlDocument().to_parent(None, SomeClass, t, elt, 'test_namespace')
+ elt = etree.Element("test")
+ XmlDocument().to_parent(None, SomeClass, t, elt, "test_namespace")
elt = elt[0]
print((etree.tostring(elt, pretty_print=True)))
@@ -162,5 +167,6 @@ def test_serialize_simple_array(self):
ret = XmlDocument().from_element(None, SomeClass, elt)
self.assertEqual(t.days, ret.days)
-if __name__ == '__main__':
+
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/model/test_exception.py b/spyne/test/model/test_exception.py
index 1b436a389..33e2d655b 100755
--- a/spyne/test/model/test_exception.py
+++ b/spyne/test/model/test_exception.py
@@ -18,97 +18,102 @@
#
import unittest
-from spyne.test import FakeApp
+
from spyne.interface import Interface
from spyne.interface.wsdl import Wsdl11
-from spyne.protocol.xml import XmlDocument
from spyne.model.fault import Fault
+from spyne.protocol.xml import XmlDocument
+from spyne.test import FakeApp
+
class FaultTests(unittest.TestCase):
def test_ctor_defaults(self):
fault = Fault()
- self.assertEqual(fault.faultcode, 'Server')
- self.assertEqual(fault.faultstring, 'Fault')
- self.assertEqual(fault.faultactor, '')
+ self.assertEqual(fault.faultcode, "Server")
+ self.assertEqual(fault.faultstring, "Fault")
+ self.assertEqual(fault.faultactor, "")
self.assertEqual(fault.detail, None)
self.assertEqual(repr(fault), "Fault(Server: 'Fault')")
def test_ctor_faultcode_w_senv_prefix(self):
- fault = Fault(faultcode='Other')
- self.assertEqual(fault.faultcode, 'Other')
+ fault = Fault(faultcode="Other")
+ self.assertEqual(fault.faultcode, "Other")
self.assertEqual(repr(fault), "Fault(Other: 'Fault')")
def test_ctor_explicit_faultstring(self):
- fault = Fault(faultstring='Testing')
- self.assertEqual(fault.faultstring, 'Testing')
+ fault = Fault(faultstring="Testing")
+ self.assertEqual(fault.faultstring, "Testing")
self.assertEqual(repr(fault), "Fault(Server: 'Testing')")
def test_to_parent_wo_detail(self):
from lxml.etree import Element
+
import spyne.const.xml
+
ns_soap_env = spyne.const.xml.NS_SOAP11_ENV
soap_env = spyne.const.xml.PREFMAP[spyne.const.xml.NS_SOAP11_ENV]
- element = Element('testing')
+ element = Element("testing")
fault = Fault()
cls = Fault
- XmlDocument().to_parent(None, cls, fault, element, 'urn:ignored')
+ XmlDocument().to_parent(None, cls, fault, element, "urn:ignored")
(child,) = element.getchildren()
- self.assertEqual(child.tag, '{%s}Fault' % ns_soap_env)
- self.assertEqual(child.find('faultcode').text, '%s:Server' % soap_env)
- self.assertEqual(child.find('faultstring').text, 'Fault')
- self.assertEqual(child.find('faultactor').text, '')
- self.assertFalse(child.findall('detail'))
+ self.assertEqual(child.tag, "{%s}Fault" % ns_soap_env)
+ self.assertEqual(child.find("faultcode").text, "%s:Server" % soap_env)
+ self.assertEqual(child.find("faultstring").text, "Fault")
+ self.assertEqual(child.find("faultactor").text, "")
+ self.assertFalse(child.findall("detail"))
def test_to_parent_w_detail(self):
from lxml.etree import Element
- element = Element('testing')
- detail = Element('something')
+
+ element = Element("testing")
+ detail = Element("something")
fault = Fault(detail=detail)
cls = Fault
- XmlDocument().to_parent(None, cls, fault, element, 'urn:ignored')
+ XmlDocument().to_parent(None, cls, fault, element, "urn:ignored")
(child,) = element.getchildren()
- self.assertTrue(child.find('detail').find('something') is detail)
+ self.assertTrue(child.find("detail").find("something") is detail)
def test_from_xml_wo_detail(self):
- from lxml.etree import Element
- from lxml.etree import SubElement
- from spyne.const.xml import PREFMAP, SOAP11_ENV, NS_SOAP11_ENV
+ from lxml.etree import Element, SubElement
+
+ from spyne.const.xml import NS_SOAP11_ENV, PREFMAP, SOAP11_ENV
soap_env = PREFMAP[NS_SOAP11_ENV]
- element = Element(SOAP11_ENV('Fault'))
+ element = Element(SOAP11_ENV("Fault"))
- fcode = SubElement(element, 'faultcode')
- fcode.text = '%s:other' % soap_env
- fstr = SubElement(element, 'faultstring')
- fstr.text = 'Testing'
- actor = SubElement(element, 'faultactor')
- actor.text = 'phreddy'
+ fcode = SubElement(element, "faultcode")
+ fcode.text = "%s:other" % soap_env
+ fstr = SubElement(element, "faultstring")
+ fstr.text = "Testing"
+ actor = SubElement(element, "faultactor")
+ actor.text = "phreddy"
fault = XmlDocument().from_element(None, Fault, element)
- self.assertEqual(fault.faultcode, '%s:other' % soap_env)
- self.assertEqual(fault.faultstring, 'Testing')
- self.assertEqual(fault.faultactor, 'phreddy')
+ self.assertEqual(fault.faultcode, "%s:other" % soap_env)
+ self.assertEqual(fault.faultstring, "Testing")
+ self.assertEqual(fault.faultactor, "phreddy")
self.assertEqual(fault.detail, None)
def test_from_xml_w_detail(self):
- from lxml.etree import Element
- from lxml.etree import SubElement
+ from lxml.etree import Element, SubElement
+
from spyne.const.xml import SOAP11_ENV
- element = Element(SOAP11_ENV('Fault'))
- fcode = SubElement(element, 'faultcode')
- fcode.text = 'soap11env:other'
- fstr = SubElement(element, 'faultstring')
- fstr.text = 'Testing'
- actor = SubElement(element, 'faultactor')
- actor.text = 'phreddy'
- detail = SubElement(element, 'detail')
+ element = Element(SOAP11_ENV("Fault"))
+ fcode = SubElement(element, "faultcode")
+ fcode.text = "soap11env:other"
+ fstr = SubElement(element, "faultstring")
+ fstr.text = "Testing"
+ actor = SubElement(element, "faultactor")
+ actor.text = "phreddy"
+ detail = SubElement(element, "detail")
fault = XmlDocument().from_element(None, Fault, element)
@@ -118,55 +123,57 @@ def test_add_to_schema_no_extends(self):
from spyne.const.xml import XSD
class cls(Fault):
- __namespace__='ns'
+ __namespace__ = "ns"
+
@classmethod
def get_type_name_ns(self, app):
- return 'testing:My'
+ return "testing:My"
interface = Interface(FakeApp())
interface.add_class(cls)
pref = cls.get_namespace_prefix(interface)
wsdl = Wsdl11(interface)
- wsdl.build_interface_document('prot://addr')
+ wsdl.build_interface_document("prot://addr")
schema = wsdl.get_schema_info(pref)
self.assertEqual(len(schema.types), 1)
- c_cls = interface.classes['{ns}cls']
+ c_cls = interface.classes["{ns}cls"]
c_elt = schema.types[0]
self.assertTrue(c_cls is cls)
- self.assertEqual(c_elt.tag, XSD('complexType'))
- self.assertEqual(c_elt.get('name'), 'cls')
+ self.assertEqual(c_elt.tag, XSD("complexType"))
+ self.assertEqual(c_elt.get("name"), "cls")
self.assertEqual(len(schema.elements), 1)
e_elt = schema.elements.values()[0]
- self.assertEqual(e_elt.tag, XSD('element'))
- self.assertEqual(e_elt.get('name'), 'cls')
- self.assertEqual(e_elt.get('type'), 'testing:My')
+ self.assertEqual(e_elt.tag, XSD("element"))
+ self.assertEqual(e_elt.get("name"), "cls")
+ self.assertEqual(e_elt.get("type"), "testing:My")
self.assertEqual(len(e_elt), 0)
def test_add_to_schema_w_extends(self):
from spyne.const.xml import XSD
class base(Fault):
- __namespace__ = 'ns'
+ __namespace__ = "ns"
@classmethod
def get_type_name_ns(self, app):
- return 'testing:Base'
+ return "testing:Base"
class cls(Fault):
- __namespace__ = 'ns'
+ __namespace__ = "ns"
+
@classmethod
def get_type_name_ns(self, app):
- return 'testing:My'
+ return "testing:My"
interface = Interface(FakeApp())
interface.add_class(cls)
pref = cls.get_namespace_prefix(interface)
wsdl = Wsdl11(interface)
- wsdl.build_interface_document('prot://addr')
+ wsdl.build_interface_document("prot://addr")
schema = wsdl.get_schema_info(pref)
self.assertEqual(len(schema.types), 1)
@@ -176,13 +183,15 @@ def get_type_name_ns(self, app):
c_elt = next(iter(schema.types.values()))
self.assertTrue(c_cls is cls)
- self.assertEqual(c_elt.tag, XSD('complexType'))
- self.assertEqual(c_elt.get('name'), 'cls')
+ self.assertEqual(c_elt.tag, XSD("complexType"))
+ self.assertEqual(c_elt.get("name"), "cls")
from lxml import etree
+
print(etree.tostring(c_elt, pretty_print=True))
self.assertEqual(len(c_elt), 0)
+
class DummySchemaEntries:
def __init__(self, app):
self.app = app
@@ -196,5 +205,5 @@ def add_element(self, cls, elt):
self._elements.append((cls, elt))
-if __name__ == '__main__': #pragma NO COVERAGE
+if __name__ == "__main__": # pragma NO COVERAGE
unittest.main()
diff --git a/spyne/test/model/test_primitive.py b/spyne/test/model/test_primitive.py
index a42a8171a..8e108514e 100755
--- a/spyne/test/model/test_primitive.py
+++ b/spyne/test/model/test_primitive.py
@@ -20,31 +20,46 @@
from __future__ import print_function
-import re
-import uuid
import datetime
+import re
import unittest
+import uuid
import warnings
-
-import pytz
-import spyne
-
from datetime import timedelta
+import pytz
from lxml import etree
-from spyne.model.primitive._base import re_match_with_span as rmws
-from spyne.util import six
+import spyne
+from spyne import (
+ AnyDict,
+ Array,
+ Boolean,
+ ComplexModel,
+ Date,
+ DateTime,
+ Decimal,
+ Duration,
+ Float,
+ Integer,
+ Integer16,
+ MediaType,
+ MimeType,
+ MimeTypeStrict,
+ ModelBase,
+ Null,
+ NumberLimitsWarning,
+ String,
+ Time,
+ Unicode,
+ Uuid,
+)
from spyne.const import xml as ns
-
-from spyne import Null, AnyDict, Uuid, Array, ComplexModel, Date, Time, \
- Boolean, DateTime, Duration, Float, Integer, NumberLimitsWarning, Unicode, \
- String, Decimal, Integer16, ModelBase, MimeType, MimeTypeStrict, MediaType
-
+from spyne.model.primitive._base import re_match_with_span as rmws
from spyne.protocol import ProtocolBase
from spyne.protocol.xml import XmlDocument
-ns_test = 'test_namespace'
+ns_test = "test_namespace"
class TestCast(unittest.TestCase):
@@ -55,52 +70,56 @@ class TestPrimitive(unittest.TestCase):
def test_mime_type_family(self):
mime_attr = MimeType.Attributes
mime_strict_attr = MimeTypeStrict.Attributes
- assert rmws(mime_attr, u'application/foo')
- assert not rmws(mime_attr, u'application/ foo')
- assert not rmws(mime_attr, u'application/')
- assert rmws(mime_attr, u'foo/bar')
- assert not rmws(mime_attr, u'foo/bar ')
- assert not rmws(mime_strict_attr, u'foo/bar')
+ assert rmws(mime_attr, "application/foo")
+ assert not rmws(mime_attr, "application/ foo")
+ assert not rmws(mime_attr, "application/")
+ assert rmws(mime_attr, "foo/bar")
+ assert not rmws(mime_attr, "foo/bar ")
+ assert not rmws(mime_strict_attr, "foo/bar")
media_attr = MediaType.Attributes
media_strict_attr = MediaType.Attributes
print(media_attr.pattern)
- assert rmws(media_attr, u'text/plain')
- assert not rmws(media_attr, u' text/plain')
- assert rmws(media_attr, u'text/plain;')
- assert rmws(media_attr, u'text/plain;charset=utf-8')
- assert rmws(media_attr, u'text/plain; charset="utf-8"')
- assert rmws(media_attr, u'text/plain; charset=utf-8')
- assert rmws(media_attr, u'text/plain; charset=utf-8 ')
- assert rmws(media_attr, u'text/plain; charset=utf-8;')
- assert rmws(media_attr, u'text/plain; charset=utf-8; ')
- assert not rmws(media_attr, u'text/plain; charset=utf-8; foo')
- assert not rmws(media_attr, u'text/plain; charset=utf-8; foo=')
- assert rmws(media_attr, u'text/plain; charset=utf-8; foo=""')
- assert rmws(media_attr, u'text/plain; charset=utf-8; foo="";')
- assert rmws(media_attr, u'text/plain; charset=utf-8; foo=""; ')
- assert rmws(media_attr, u'text/plain; charset=utf-8; foo=""; ')
- assert not rmws(media_attr, u'text/plain;; charset=utf-8; foo=""')
- assert not rmws(media_attr, u'text/plain;;; charset=utf-8; foo=""')
- assert not rmws(media_attr, u'text/plain; charset=utf-8;; foo=""')
- assert not rmws(media_attr, u'text/plain; charset=utf-8;;; foo=""')
- assert not rmws(media_attr, u'text/plain; charset=utf-8;;; foo="";')
- assert not rmws(media_attr, u'text/plain; charset=utf-8;;; foo=""; ; ')
-
- assert not rmws(media_strict_attr, u' applicaton/json;')
+ assert rmws(media_attr, "text/plain")
+ assert not rmws(media_attr, " text/plain")
+ assert rmws(media_attr, "text/plain;")
+ assert rmws(media_attr, "text/plain;charset=utf-8")
+ assert rmws(media_attr, 'text/plain; charset="utf-8"')
+ assert rmws(media_attr, "text/plain; charset=utf-8")
+ assert rmws(media_attr, "text/plain; charset=utf-8 ")
+ assert rmws(media_attr, "text/plain; charset=utf-8;")
+ assert rmws(media_attr, "text/plain; charset=utf-8; ")
+ assert not rmws(media_attr, "text/plain; charset=utf-8; foo")
+ assert not rmws(media_attr, "text/plain; charset=utf-8; foo=")
+ assert rmws(media_attr, 'text/plain; charset=utf-8; foo=""')
+ assert rmws(media_attr, 'text/plain; charset=utf-8; foo="";')
+ assert rmws(media_attr, 'text/plain; charset=utf-8; foo=""; ')
+ assert rmws(media_attr, 'text/plain; charset=utf-8; foo=""; ')
+ assert not rmws(media_attr, 'text/plain;; charset=utf-8; foo=""')
+ assert not rmws(media_attr, 'text/plain;;; charset=utf-8; foo=""')
+ assert not rmws(media_attr, 'text/plain; charset=utf-8;; foo=""')
+ assert not rmws(media_attr, 'text/plain; charset=utf-8;;; foo=""')
+ assert not rmws(media_attr, 'text/plain; charset=utf-8;;; foo="";')
+ assert not rmws(media_attr, 'text/plain; charset=utf-8;;; foo=""; ; ')
+
+ assert not rmws(media_strict_attr, " applicaton/json;")
assert MediaType
-
def test_getitem_cust(self):
assert Unicode[dict(max_len=2)].Attributes.max_len
def test_ancestors(self):
- class A(ComplexModel): i = Integer
- class B(A): i2 = Integer
- class C(B): i3 = Integer
+ class A(ComplexModel):
+ i = Integer
+
+ class B(A):
+ i2 = Integer
+
+ class C(B):
+ i3 = Integer
assert C.ancestors() == [B, A]
assert B.ancestors() == [A]
@@ -174,28 +193,29 @@ def test_decimal(self):
def test_decimal_format(self):
f = 123456
- str_format = '${0}'
- element = etree.Element('test')
- XmlDocument().to_parent(None, Decimal(str_format=str_format), f,
- element, ns_test)
+ str_format = "${0}"
+ element = etree.Element("test")
+ XmlDocument().to_parent(
+ None, Decimal(str_format=str_format), f, element, ns_test
+ )
element = element[0]
- self.assertEqual(element.text, '$123456')
+ self.assertEqual(element.text, "$123456")
def test_string(self):
s = String()
- element = etree.Element('test')
- XmlDocument().to_parent(None, String, 'value', element, ns_test)
+ element = etree.Element("test")
+ XmlDocument().to_parent(None, String, "value", element, ns_test)
element = element[0]
- self.assertEqual(element.text, 'value')
+ self.assertEqual(element.text, "value")
value = XmlDocument().from_element(None, String, element)
- self.assertEqual(value, 'value')
+ self.assertEqual(value, "value")
def test_datetime(self):
n = datetime.datetime.now(pytz.utc)
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, DateTime, n, element, ns_test)
element = element[0]
@@ -207,53 +227,43 @@ def test_datetime_format(self):
n = datetime.datetime.now().replace(microsecond=0)
format = "%Y %m %d %H %M %S"
- element = etree.Element('test')
- XmlDocument().to_parent(None, DateTime(dt_format=format), n, element,
- ns_test)
+ element = etree.Element("test")
+ XmlDocument().to_parent(None, DateTime(dt_format=format), n, element, ns_test)
element = element[0]
assert element.text == datetime.datetime.strftime(n, format)
- dt = XmlDocument().from_element(None, DateTime(dt_format=format),
- element)
+ dt = XmlDocument().from_element(None, DateTime(dt_format=format), element)
assert n == dt
def test_datetime_unicode_format(self):
n = datetime.datetime.now().replace(microsecond=0)
- format = u"%Y %m %d\u00a0%H %M %S"
+ format = "%Y %m %d\u00a0%H %M %S"
- element = etree.Element('test')
- XmlDocument().to_parent(None, DateTime(dt_format=format), n,
- element, ns_test)
+ element = etree.Element("test")
+ XmlDocument().to_parent(None, DateTime(dt_format=format), n, element, ns_test)
element = element[0]
- if six.PY2:
- assert element.text == n.strftime(format.encode('utf8')) \
- .decode('utf8')
- else:
- assert element.text == n.strftime(format)
+ assert element.text == n.strftime(format)
- dt = XmlDocument().from_element(None, DateTime(dt_format=format),
- element)
+ dt = XmlDocument().from_element(None, DateTime(dt_format=format), element)
assert n == dt
def test_date_format(self):
t = datetime.date.today()
format = "%Y-%m-%d"
- element = etree.Element('test')
- XmlDocument().to_parent(None,
- Date(date_format=format), t, element, ns_test)
+ element = etree.Element("test")
+ XmlDocument().to_parent(None, Date(date_format=format), t, element, ns_test)
assert element[0].text == datetime.date.strftime(t, format)
- dt = XmlDocument().from_element(None,
- Date(date_format=format), element[0])
+ dt = XmlDocument().from_element(None, Date(date_format=format), element[0])
assert t == dt
def test_datetime_timezone(self):
import pytz
- n = datetime.datetime.now(pytz.timezone('EST'))
- element = etree.Element('test')
+ n = datetime.datetime.now(pytz.timezone("EST"))
+ element = etree.Element("test")
cls = DateTime(as_timezone=pytz.utc, timezone=False)
XmlDocument().to_parent(None, cls, n, element, ns_test)
element = element[0]
@@ -266,11 +276,11 @@ def test_datetime_timezone(self):
self.assertEqual(c, dt)
def test_date_timezone(self):
- elt = etree.Element('wot')
- elt.text = '2013-08-09+02:00'
+ elt = etree.Element("wot")
+ elt.text = "2013-08-09+02:00"
dt = XmlDocument().from_element(None, Date, elt)
print("ok without validation.")
- dt = XmlDocument(validator='soft').from_element(None, Date, elt)
+ dt = XmlDocument(validator="soft").from_element(None, Date, elt)
print(dt)
def test_time(self):
@@ -320,8 +330,8 @@ def test_date(self):
self.assertEqual(n, dt)
def test_utcdatetime(self):
- datestring = '2007-05-15T13:40:44Z'
- e = etree.Element('test')
+ datestring = "2007-05-15T13:40:44Z"
+ e = etree.Element("test")
e.text = datestring
dt = XmlDocument().from_element(None, DateTime, e)
@@ -330,8 +340,8 @@ def test_utcdatetime(self):
self.assertEqual(dt.month, 5)
self.assertEqual(dt.day, 15)
- datestring = '2007-05-15T13:40:44.003Z'
- e = etree.Element('test')
+ datestring = "2007-05-15T13:40:44.003Z"
+ e = etree.Element("test")
e.text = datestring
dt = XmlDocument().from_element(None, DateTime, e)
@@ -341,74 +351,79 @@ def test_utcdatetime(self):
self.assertEqual(dt.day, 15)
def test_date_exclusive_boundaries(self):
- test_model = Date.customize(gt=datetime.date(2016, 1, 1),
- lt=datetime.date(2016, 2, 1))
+ test_model = Date.customize(
+ gt=datetime.date(2016, 1, 1), lt=datetime.date(2016, 2, 1)
+ )
self.assertFalse(
- test_model.validate_native(test_model, datetime.date(2016, 1, 1)))
+ test_model.validate_native(test_model, datetime.date(2016, 1, 1))
+ )
self.assertFalse(
- test_model.validate_native(test_model, datetime.date(2016, 2, 1)))
+ test_model.validate_native(test_model, datetime.date(2016, 2, 1))
+ )
def test_date_inclusive_boundaries(self):
- test_model = Date.customize(ge=datetime.date(2016, 1, 1),
- le=datetime.date(2016, 2, 1))
+ test_model = Date.customize(
+ ge=datetime.date(2016, 1, 1), le=datetime.date(2016, 2, 1)
+ )
self.assertTrue(
- test_model.validate_native(test_model, datetime.date(2016, 1, 1)))
+ test_model.validate_native(test_model, datetime.date(2016, 1, 1))
+ )
self.assertTrue(
- test_model.validate_native(test_model, datetime.date(2016, 2, 1)))
+ test_model.validate_native(test_model, datetime.date(2016, 2, 1))
+ )
def test_datetime_exclusive_boundaries(self):
test_model = DateTime.customize(
- gt=datetime.datetime(2016, 1, 1, 12, 00)
- .replace(tzinfo=spyne.LOCAL_TZ),
- lt=datetime.datetime(2016, 2, 1, 12, 00)
- .replace(tzinfo=spyne.LOCAL_TZ),
+ gt=datetime.datetime(2016, 1, 1, 12, 00).replace(tzinfo=spyne.LOCAL_TZ),
+ lt=datetime.datetime(2016, 2, 1, 12, 00).replace(tzinfo=spyne.LOCAL_TZ),
+ )
+ self.assertFalse(
+ test_model.validate_native(
+ test_model, datetime.datetime(2016, 1, 1, 12, 00)
+ )
+ )
+ self.assertFalse(
+ test_model.validate_native(
+ test_model, datetime.datetime(2016, 2, 1, 12, 00)
+ )
)
- self.assertFalse(test_model.validate_native(test_model,
- datetime.datetime(2016, 1, 1, 12, 00)))
- self.assertFalse(test_model.validate_native(test_model,
- datetime.datetime(2016, 2, 1, 12, 00)))
def test_datetime_inclusive_boundaries(self):
test_model = DateTime.customize(
- ge=datetime.datetime(2016, 1, 1, 12, 00)
- .replace(tzinfo=spyne.LOCAL_TZ),
- le=datetime.datetime(2016, 2, 1, 12, 00)
- .replace(tzinfo=spyne.LOCAL_TZ)
+ ge=datetime.datetime(2016, 1, 1, 12, 00).replace(tzinfo=spyne.LOCAL_TZ),
+ le=datetime.datetime(2016, 2, 1, 12, 00).replace(tzinfo=spyne.LOCAL_TZ),
)
- self.assertTrue(test_model.validate_native(test_model,
- datetime.datetime(2016, 1, 1, 12, 00)))
- self.assertTrue(test_model.validate_native(test_model,
- datetime.datetime(2016, 2, 1, 12, 00)))
+ self.assertTrue(
+ test_model.validate_native(
+ test_model, datetime.datetime(2016, 1, 1, 12, 00)
+ )
+ )
+ self.assertTrue(
+ test_model.validate_native(
+ test_model, datetime.datetime(2016, 2, 1, 12, 00)
+ )
+ )
def test_time_exclusive_boundaries(self):
- test_model = Time.customize(gt=datetime.time(12, 00),
- lt=datetime.time(13, 00))
+ test_model = Time.customize(gt=datetime.time(12, 00), lt=datetime.time(13, 00))
- self.assertFalse(
- test_model.validate_native(test_model, datetime.time(12, 00)))
- self.assertFalse(
- test_model.validate_native(test_model, datetime.time(13, 00)))
+ self.assertFalse(test_model.validate_native(test_model, datetime.time(12, 00)))
+ self.assertFalse(test_model.validate_native(test_model, datetime.time(13, 00)))
def test_time_inclusive_boundaries(self):
- test_model = Time.customize(ge=datetime.time(12, 00),
- le=datetime.time(13, 00))
+ test_model = Time.customize(ge=datetime.time(12, 00), le=datetime.time(13, 00))
- self.assertTrue(
- test_model.validate_native(test_model, datetime.time(12, 00)))
- self.assertTrue(
- test_model.validate_native(test_model, datetime.time(13, 00)))
+ self.assertTrue(test_model.validate_native(test_model, datetime.time(12, 00)))
+ self.assertTrue(test_model.validate_native(test_model, datetime.time(13, 00)))
def test_datetime_extreme_boundary(self):
- self.assertTrue(
- DateTime.validate_native(DateTime, datetime.datetime.min))
- self.assertTrue(
- DateTime.validate_native(DateTime, datetime.datetime.max))
+ self.assertTrue(DateTime.validate_native(DateTime, datetime.datetime.min))
+ self.assertTrue(DateTime.validate_native(DateTime, datetime.datetime.max))
def test_time_extreme_boundary(self):
self.assertTrue(Time.validate_native(Time, datetime.time(0, 0, 0, 0)))
- self.assertTrue(
- Time.validate_native(Time, datetime.time(23, 59, 59, 999999)))
+ self.assertTrue(Time.validate_native(Time, datetime.time(23, 59, 59, 999999)))
def test_date_extreme_boundary(self):
self.assertTrue(Date.validate_native(Date, datetime.date.min))
@@ -418,11 +433,11 @@ def test_integer(self):
i = 12
integer = Integer()
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, Integer, i, element, ns_test)
element = element[0]
- self.assertEqual(element.text, '12')
+ self.assertEqual(element.text, "12")
value = XmlDocument().from_element(None, integer, element)
self.assertEqual(value, i)
@@ -469,18 +484,18 @@ def test_large_integer(self):
i = 128375873458473
integer = Integer()
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, Integer, i, element, ns_test)
element = element[0]
- self.assertEqual(element.text, '128375873458473')
+ self.assertEqual(element.text, "128375873458473")
value = XmlDocument().from_element(None, integer, element)
self.assertEqual(value, i)
def test_float(self):
f = 1.22255645
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, Float, f, element, ns_test)
element = element[0]
@@ -493,9 +508,9 @@ def test_array(self):
type = Array(String)
type.resolve_namespace(type, "zbank")
- values = ['a', 'b', 'c', 'd', 'e', 'f']
+ values = ["a", "b", "c", "d", "e", "f"]
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, type, values, element, ns_test)
element = element[0]
@@ -510,7 +525,7 @@ def test_array_empty(self):
values = []
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, type, values, element, ns_test)
element = element[0]
@@ -520,25 +535,25 @@ def test_array_empty(self):
self.assertEqual(len(values2), 0)
def test_unicode(self):
- s = u'\x34\x55\x65\x34'
+ s = "\x34\x55\x65\x34"
self.assertEqual(4, len(s))
- element = etree.Element('test')
- XmlDocument().to_parent(None, String, s, element, 'test_ns')
+ element = etree.Element("test")
+ XmlDocument().to_parent(None, String, s, element, "test_ns")
element = element[0]
value = XmlDocument().from_element(None, String, element)
self.assertEqual(value, s)
def test_unicode_pattern_mult_cust(self):
- assert Unicode(pattern='a').Attributes.pattern == 'a'
- assert Unicode(pattern='a')(5).Attributes.pattern == 'a'
+ assert Unicode(pattern="a").Attributes.pattern == "a"
+ assert Unicode(pattern="a")(5).Attributes.pattern == "a"
def test_unicode_upattern(self):
- patt = r'[\w .-]+'
+ patt = r"[\w .-]+"
attr = Unicode(unicode_pattern=patt).Attributes
assert attr.pattern == patt
assert attr._pattern_re.flags & re.UNICODE
- assert attr._pattern_re.match(u"Ğ Ğ ç .-")
- assert attr._pattern_re.match(u"\t") is None
+ assert attr._pattern_re.match("Ğ Ğ ç .-")
+ assert attr._pattern_re.match("\t") is None
def test_unicode_nullable_mult_cust_false(self):
assert Unicode(nullable=False).Attributes.nullable == False
@@ -549,12 +564,12 @@ def test_unicode_nullable_mult_cust_true(self):
assert Unicode(nullable=True)(5).Attributes.nullable == True
def test_null(self):
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, Null, None, element, ns_test)
print(etree.tostring(element))
element = element[0]
- self.assertTrue(bool(element.attrib.get(ns.XSI('nil'))))
+ self.assertTrue(bool(element.attrib.get(ns.XSI("nil"))))
value = XmlDocument().from_element(None, Null, element)
self.assertEqual(None, value)
@@ -562,17 +577,17 @@ def test_point(self):
from spyne.model.primitive.spatial import _get_point_pattern
a = re.compile(_get_point_pattern(2))
- assert a.match('POINT (10 40)') is not None
- assert a.match('POINT(10 40)') is not None
+ assert a.match("POINT (10 40)") is not None
+ assert a.match("POINT(10 40)") is not None
- assert a.match('POINT(10.0 40)') is not None
- assert a.match('POINT(1.310e4 40)') is not None
+ assert a.match("POINT(10.0 40)") is not None
+ assert a.match("POINT(1.310e4 40)") is not None
def test_multipoint(self):
from spyne.model.primitive.spatial import _get_multipoint_pattern
a = re.compile(_get_multipoint_pattern(2))
- assert a.match('MULTIPOINT (10 40, 40 30, 20 20, 30 10)') is not None
+ assert a.match("MULTIPOINT (10 40, 40 30, 20 20, 30 10)") is not None
# FIXME:
# assert a.match('MULTIPOINT ((10 40), (40 30), (20 20), (30 10))') is not None
@@ -580,70 +595,69 @@ def test_linestring(self):
from spyne.model.primitive.spatial import _get_linestring_pattern
a = re.compile(_get_linestring_pattern(2))
- assert a.match('LINESTRING (30 10, 10 30, 40 40)') is not None
+ assert a.match("LINESTRING (30 10, 10 30, 40 40)") is not None
def test_multilinestring(self):
from spyne.model.primitive.spatial import _get_multilinestring_pattern
a = re.compile(_get_multilinestring_pattern(2))
- assert a.match('''MULTILINESTRING ((10 10, 20 20, 10 40),
- (40 40, 30 30, 40 20, 30 10))''') is not None
+ assert a.match("""MULTILINESTRING ((10 10, 20 20, 10 40),
+ (40 40, 30 30, 40 20, 30 10))""") is not None
def test_polygon(self):
from spyne.model.primitive.spatial import _get_polygon_pattern
a = re.compile(_get_polygon_pattern(2))
- assert a.match(
- 'POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))') is not None
+ assert a.match("POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))") is not None
def test_multipolygon(self):
from spyne.model.primitive.spatial import _get_multipolygon_pattern
a = re.compile(_get_multipolygon_pattern(2))
- assert a.match('''MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),
- ((15 5, 40 10, 10 20, 5 10, 15 5)))''') is not None
- assert a.match('''MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),
+ assert a.match("""MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),
+ ((15 5, 40 10, 10 20, 5 10, 15 5)))""") is not None
+ assert a.match("""MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),
((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),
- (30 20, 20 25, 20 15, 30 20)))''') is not None
+ (30 20, 20 25, 20 15, 30 20)))""") is not None
def test_boolean(self):
- b = etree.Element('test')
+ b = etree.Element("test")
XmlDocument().to_parent(None, Boolean, True, b, ns_test)
b = b[0]
- self.assertEqual('true', b.text)
+ self.assertEqual("true", b.text)
- b = etree.Element('test')
+ b = etree.Element("test")
XmlDocument().to_parent(None, Boolean, 0, b, ns_test)
b = b[0]
- self.assertEqual('false', b.text)
+ self.assertEqual("false", b.text)
- b = etree.Element('test')
+ b = etree.Element("test")
XmlDocument().to_parent(None, Boolean, 1, b, ns_test)
b = b[0]
- self.assertEqual('true', b.text)
+ self.assertEqual("true", b.text)
b = XmlDocument().from_element(None, Boolean, b)
self.assertEqual(b, True)
- b = etree.Element('test')
+ b = etree.Element("test")
XmlDocument().to_parent(None, Boolean, False, b, ns_test)
b = b[0]
- self.assertEqual('false', b.text)
+ self.assertEqual("false", b.text)
b = XmlDocument().from_element(None, Boolean, b)
self.assertEqual(b, False)
- b = etree.Element('test')
+ b = etree.Element("test")
XmlDocument().to_parent(None, Boolean, None, b, ns_test)
b = b[0]
- self.assertEqual('true', b.get(ns.XSI('nil')))
+ self.assertEqual("true", b.get(ns.XSI("nil")))
b = XmlDocument().from_element(None, Boolean, b)
self.assertEqual(b, None)
def test_new_type(self):
"""Customized primitives go into namespace based on module name."""
- custom_type = Unicode(pattern='123')
+ custom_type = Unicode(pattern="123")
self.assertEqual(custom_type.get_namespace(), custom_type.__module__)
def test_default_nullable(self):
@@ -664,89 +678,137 @@ def test_simple_type_explicit_customization(self):
def test_anydict_customization(self):
from spyne.model import json
- assert isinstance(
- AnyDict.customize(store_as='json').Attributes.store_as, json)
+
+ assert isinstance(AnyDict.customize(store_as="json").Attributes.store_as, json)
def test_uuid_serialize(self):
- value = uuid.UUID('12345678123456781234567812345678')
-
- assert ProtocolBase().to_unicode(Uuid, value) \
- == '12345678-1234-5678-1234-567812345678'
- assert ProtocolBase().to_unicode(Uuid(serialize_as='hex'), value) \
- == '12345678123456781234567812345678'
- assert ProtocolBase().to_unicode(Uuid(serialize_as='urn'), value) \
- == 'urn:uuid:12345678-1234-5678-1234-567812345678'
- assert ProtocolBase().to_unicode(Uuid(serialize_as='bytes'), value) \
- == b'\x124Vx\x124Vx\x124Vx\x124Vx'
- assert ProtocolBase().to_unicode(Uuid(serialize_as='bytes_le'), value) \
- == b'xV4\x124\x12xV\x124Vx\x124Vx'
- assert ProtocolBase().to_unicode(Uuid(serialize_as='fields'), value) \
- == (305419896, 4660, 22136, 18, 52, 95073701484152)
- assert ProtocolBase().to_unicode(Uuid(serialize_as='int'), value) \
- == 24197857161011715162171839636988778104
+ value = uuid.UUID("12345678123456781234567812345678")
+
+ assert (
+ ProtocolBase().to_unicode(Uuid, value)
+ == "12345678-1234-5678-1234-567812345678"
+ )
+ assert (
+ ProtocolBase().to_unicode(Uuid(serialize_as="hex"), value)
+ == "12345678123456781234567812345678"
+ )
+ assert (
+ ProtocolBase().to_unicode(Uuid(serialize_as="urn"), value)
+ == "urn:uuid:12345678-1234-5678-1234-567812345678"
+ )
+ assert (
+ ProtocolBase().to_unicode(Uuid(serialize_as="bytes"), value)
+ == b"\x124Vx\x124Vx\x124Vx\x124Vx"
+ )
+ assert (
+ ProtocolBase().to_unicode(Uuid(serialize_as="bytes_le"), value)
+ == b"xV4\x124\x12xV\x124Vx\x124Vx"
+ )
+ assert ProtocolBase().to_unicode(Uuid(serialize_as="fields"), value) == (
+ 305419896,
+ 4660,
+ 22136,
+ 18,
+ 52,
+ 95073701484152,
+ )
+ assert (
+ ProtocolBase().to_unicode(Uuid(serialize_as="int"), value)
+ == 24197857161011715162171839636988778104
+ )
def test_uuid_deserialize(self):
- value = uuid.UUID('12345678123456781234567812345678')
-
- assert ProtocolBase().from_unicode(Uuid,
- '12345678-1234-5678-1234-567812345678') == value
- assert ProtocolBase().from_unicode(Uuid(serialize_as='hex'),
- '12345678123456781234567812345678') == value
- assert ProtocolBase().from_unicode(Uuid(serialize_as='urn'),
- 'urn:uuid:12345678-1234-5678-1234-567812345678') == value
- assert ProtocolBase().from_bytes(Uuid(serialize_as='bytes'),
- b'\x124Vx\x124Vx\x124Vx\x124Vx') == value
- assert ProtocolBase().from_bytes(Uuid(serialize_as='bytes_le'),
- b'xV4\x124\x12xV\x124Vx\x124Vx') == value
- assert ProtocolBase().from_unicode(Uuid(serialize_as='fields'),
- (305419896, 4660, 22136, 18, 52, 95073701484152)) == value
- assert ProtocolBase().from_unicode(Uuid(serialize_as='int'),
- 24197857161011715162171839636988778104) == value
+ value = uuid.UUID("12345678123456781234567812345678")
+
+ assert (
+ ProtocolBase().from_unicode(Uuid, "12345678-1234-5678-1234-567812345678")
+ == value
+ )
+ assert (
+ ProtocolBase().from_unicode(
+ Uuid(serialize_as="hex"), "12345678123456781234567812345678"
+ )
+ == value
+ )
+ assert (
+ ProtocolBase().from_unicode(
+ Uuid(serialize_as="urn"),
+ "urn:uuid:12345678-1234-5678-1234-567812345678",
+ )
+ == value
+ )
+ assert (
+ ProtocolBase().from_bytes(
+ Uuid(serialize_as="bytes"), b"\x124Vx\x124Vx\x124Vx\x124Vx"
+ )
+ == value
+ )
+ assert (
+ ProtocolBase().from_bytes(
+ Uuid(serialize_as="bytes_le"), b"xV4\x124\x12xV\x124Vx\x124Vx"
+ )
+ == value
+ )
+ assert (
+ ProtocolBase().from_unicode(
+ Uuid(serialize_as="fields"),
+ (305419896, 4660, 22136, 18, 52, 95073701484152),
+ )
+ == value
+ )
+ assert (
+ ProtocolBase().from_unicode(
+ Uuid(serialize_as="int"), 24197857161011715162171839636988778104
+ )
+ == value
+ )
def test_uuid_validate(self):
- assert Uuid.validate_string(Uuid,
- '12345678-1234-5678-1234-567812345678')
- assert Uuid.validate_native(Uuid,
- uuid.UUID('12345678-1234-5678-1234-567812345678'))
+ assert Uuid.validate_string(Uuid, "12345678-1234-5678-1234-567812345678")
+ assert Uuid.validate_native(
+ Uuid, uuid.UUID("12345678-1234-5678-1234-567812345678")
+ )
def test_datetime_serialize_as(self):
i = 1234567890123456
v = datetime.datetime.fromtimestamp(i / 1e6)
- assert ProtocolBase().to_unicode(
- DateTime(serialize_as='sec'), v) == i//1e6
- assert ProtocolBase().to_unicode(
- DateTime(serialize_as='sec_float'), v) == i/1e6
- assert ProtocolBase().to_unicode(
- DateTime(serialize_as='msec'), v) == i//1e3
- assert ProtocolBase().to_unicode(
- DateTime(serialize_as='msec_float'), v) == i/1e3
- assert ProtocolBase().to_unicode(
- DateTime(serialize_as='usec'), v) == i
+ assert ProtocolBase().to_unicode(DateTime(serialize_as="sec"), v) == i // 1e6
+ assert (
+ ProtocolBase().to_unicode(DateTime(serialize_as="sec_float"), v) == i / 1e6
+ )
+ assert ProtocolBase().to_unicode(DateTime(serialize_as="msec"), v) == i // 1e3
+ assert (
+ ProtocolBase().to_unicode(DateTime(serialize_as="msec_float"), v) == i / 1e3
+ )
+ assert ProtocolBase().to_unicode(DateTime(serialize_as="usec"), v) == i
def test_datetime_deserialize(self):
i = 1234567890123456
v = datetime.datetime.fromtimestamp(i / 1e6)
assert ProtocolBase().from_unicode(
- DateTime(serialize_as='sec'), i//1e6) == \
- datetime.datetime.fromtimestamp(i//1e6)
- assert ProtocolBase().from_unicode(
- DateTime(serialize_as='sec_float'), i/1e6) == v
+ DateTime(serialize_as="sec"), i // 1e6
+ ) == datetime.datetime.fromtimestamp(i // 1e6)
+ assert (
+ ProtocolBase().from_unicode(DateTime(serialize_as="sec_float"), i / 1e6)
+ == v
+ )
assert ProtocolBase().from_unicode(
- DateTime(serialize_as='msec'), i//1e3) == \
- datetime.datetime.fromtimestamp(i/1e3//1000)
- assert ProtocolBase().from_unicode(
- DateTime(serialize_as='msec_float'), i/1e3) == v
+ DateTime(serialize_as="msec"), i // 1e3
+ ) == datetime.datetime.fromtimestamp(i / 1e3 // 1000)
+ assert (
+ ProtocolBase().from_unicode(DateTime(serialize_as="msec_float"), i / 1e3)
+ == v
+ )
- assert ProtocolBase().from_unicode(
- DateTime(serialize_as='usec'), i) == v
+ assert ProtocolBase().from_unicode(DateTime(serialize_as="usec"), i) == v
def test_datetime_ancient(self):
t = DateTime(dt_format="%Y-%m-%d %H:%M:%S") # to trigger strftime
v = datetime.datetime(1881, 1, 1)
- vs = '1881-01-01 00:00:00'
+ vs = "1881-01-01 00:00:00"
dt = ProtocolBase().from_unicode(t, vs)
self.assertEqual(v, dt)
@@ -755,8 +817,9 @@ def test_datetime_ancient(self):
self.assertEqual(vs, dt)
def test_custom_strftime(self):
- s = ProtocolBase.strftime(datetime.date(1800, 9, 23),
- "%Y has the same days as 1980 and 2008")
+ s = ProtocolBase.strftime(
+ datetime.date(1800, 9, 23), "%Y has the same days as 1980 and 2008"
+ )
if s != "1800 has the same days as 1980 and 2008":
raise AssertionError(s)
@@ -777,8 +840,7 @@ def test_custom_strftime(self):
testdate = startdate + one_day
while testdate < enddate:
- if (testdate.day == 1 and testdate.month == 1 and
- (testdate.year % 100 == 0)):
+ if testdate.day == 1 and testdate.month == 1 and (testdate.year % 100 == 0):
print("Testing century", testdate.year)
day = ProtocolBase.strftime(testdate, "%A")
if nextday[prevday] != day:
@@ -790,29 +852,24 @@ def test_datetime_usec(self):
# see the comments on time test for why the rounding here is weird
# rounding 0.1 µsec down
- dt = ProtocolBase().from_unicode(DateTime,
- "2015-01-01 12:12:12.0000001")
+ dt = ProtocolBase().from_unicode(DateTime, "2015-01-01 12:12:12.0000001")
self.assertEqual(datetime.datetime(2015, 1, 1, 12, 12, 12), dt)
# rounding 1.5 µsec up. 0.5 is rounded down by python 3 and up by
# python 2 so we test with 1.5 µsec instead. frikkin' nonsense.
- dt = ProtocolBase().from_unicode(DateTime,
- "2015-01-01 12:12:12.0000015")
+ dt = ProtocolBase().from_unicode(DateTime, "2015-01-01 12:12:12.0000015")
self.assertEqual(datetime.datetime(2015, 1, 1, 12, 12, 12, 2), dt)
# rounding 999998.8 µsec up
- dt = ProtocolBase().from_unicode(DateTime,
- "2015-01-01 12:12:12.9999988")
+ dt = ProtocolBase().from_unicode(DateTime, "2015-01-01 12:12:12.9999988")
self.assertEqual(datetime.datetime(2015, 1, 1, 12, 12, 12, 999999), dt)
# rounding 999999.1 µsec down
- dt = ProtocolBase().from_unicode(DateTime,
- "2015-01-01 12:12:12.9999991")
+ dt = ProtocolBase().from_unicode(DateTime, "2015-01-01 12:12:12.9999991")
self.assertEqual(datetime.datetime(2015, 1, 1, 12, 12, 12, 999999), dt)
# rounding 999999.8 µsec down, not up.
- dt = ProtocolBase().from_unicode(DateTime,
- "2015-01-01 12:12:12.9999998")
+ dt = ProtocolBase().from_unicode(DateTime, "2015-01-01 12:12:12.9999998")
self.assertEqual(datetime.datetime(2015, 1, 1, 12, 12, 12, 999999), dt)
@@ -830,18 +887,19 @@ def test_datetime_usec(self):
# nM indicates the number of minutes
# nS indicates the number of seconds
+
class SomeBlob(ComplexModel):
- __namespace__ = 'myns'
+ __namespace__ = "myns"
howlong = Duration()
class TestDurationPrimitive(unittest.TestCase):
def test_onehour_oneminute_onesecond(self):
- answer = 'PT1H1M1S'
+ answer = "PT1H1M1S"
gg = SomeBlob()
gg.howlong = timedelta(hours=1, minutes=1, seconds=1)
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, SomeBlob, gg, element, gg.get_namespace())
element = element[0]
@@ -849,7 +907,7 @@ def test_onehour_oneminute_onesecond(self):
print(etree.tostring(element, pretty_print=True))
assert element[0].text == answer
- data = element.find('{%s}howlong' % gg.get_namespace()).text
+ data = element.find("{%s}howlong" % gg.get_namespace()).text
self.assertEqual(data, answer)
s1 = XmlDocument().from_element(None, SomeBlob, element)
assert s1.howlong.total_seconds() == gg.howlong.total_seconds()
@@ -857,32 +915,31 @@ def test_onehour_oneminute_onesecond(self):
def test_4suite(self):
# borrowed from 4Suite
tests_seconds = [
- (0, u'PT0S'),
- (1, u'PT1S'),
- (59, u'PT59S'),
- (60, u'PT1M'),
- (3599, u'PT59M59S'),
- (3600, u'PT1H'),
- (86399, u'PT23H59M59S'),
- (86400, u'P1D'),
- (86400 * 60, u'P60D'),
- (86400 * 400, u'P400D')
+ (0, "PT0S"),
+ (1, "PT1S"),
+ (59, "PT59S"),
+ (60, "PT1M"),
+ (3599, "PT59M59S"),
+ (3600, "PT1H"),
+ (86399, "PT23H59M59S"),
+ (86400, "P1D"),
+ (86400 * 60, "P60D"),
+ (86400 * 400, "P400D"),
]
for secs, answer in tests_seconds:
gg = SomeBlob()
gg.howlong = timedelta(seconds=secs)
- element = etree.Element('test')
- XmlDocument()\
- .to_parent(None, SomeBlob, gg, element, gg.get_namespace())
+ element = etree.Element("test")
+ XmlDocument().to_parent(None, SomeBlob, gg, element, gg.get_namespace())
element = element[0]
print(gg.howlong)
print(etree.tostring(element, pretty_print=True))
assert element[0].text == answer
- data = element.find('{%s}howlong' % gg.get_namespace()).text
+ data = element.find("{%s}howlong" % gg.get_namespace()).text
self.assertEqual(data, answer)
s1 = XmlDocument().from_element(None, SomeBlob, element)
assert s1.howlong.total_seconds() == secs
@@ -890,30 +947,29 @@ def test_4suite(self):
for secs, answer in tests_seconds:
if secs > 0:
secs *= -1
- answer = '-' + answer
+ answer = "-" + answer
gg = SomeBlob()
gg.howlong = timedelta(seconds=secs)
- element = etree.Element('test')
- XmlDocument()\
- .to_parent(None, SomeBlob, gg, element, gg.get_namespace())
+ element = etree.Element("test")
+ XmlDocument().to_parent(None, SomeBlob, gg, element, gg.get_namespace())
element = element[0]
print(gg.howlong)
print(etree.tostring(element, pretty_print=True))
assert element[0].text == answer
- data = element.find('{%s}howlong' % gg.get_namespace()).text
+ data = element.find("{%s}howlong" % gg.get_namespace()).text
self.assertEqual(data, answer)
s1 = XmlDocument().from_element(None, SomeBlob, element)
assert s1.howlong.total_seconds() == secs
def test_duration_positive_seconds_only(self):
- answer = 'PT35S'
+ answer = "PT35S"
gg = SomeBlob()
gg.howlong = timedelta(seconds=35)
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, SomeBlob, gg, element, gg.get_namespace())
element = element[0]
@@ -921,17 +977,17 @@ def test_duration_positive_seconds_only(self):
print(etree.tostring(element, pretty_print=True))
assert element[0].text == answer
- data = element.find('{%s}howlong' % gg.get_namespace()).text
+ data = element.find("{%s}howlong" % gg.get_namespace()).text
self.assertEqual(data, answer)
s1 = XmlDocument().from_element(None, SomeBlob, element)
assert s1.howlong.total_seconds() == gg.howlong.total_seconds()
def test_duration_positive_minutes_and_seconds_only(self):
- answer = 'PT5M35S'
+ answer = "PT5M35S"
gg = SomeBlob()
gg.howlong = timedelta(minutes=5, seconds=35)
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, SomeBlob, gg, element, gg.get_namespace())
element = element[0]
@@ -939,17 +995,17 @@ def test_duration_positive_minutes_and_seconds_only(self):
print(etree.tostring(element, pretty_print=True))
assert element[0].text == answer
- data = element.find('{%s}howlong' % gg.get_namespace()).text
+ data = element.find("{%s}howlong" % gg.get_namespace()).text
self.assertEqual(data, answer)
s1 = XmlDocument().from_element(None, SomeBlob, element)
assert s1.howlong.total_seconds() == gg.howlong.total_seconds()
def test_duration_positive_milliseconds_only(self):
- answer = 'PT0.666000S'
+ answer = "PT0.666000S"
gg = SomeBlob()
gg.howlong = timedelta(milliseconds=666)
- element = etree.Element('test')
+ element = etree.Element("test")
XmlDocument().to_parent(None, SomeBlob, gg, element, gg.get_namespace())
element = element[0]
@@ -957,24 +1013,29 @@ def test_duration_positive_milliseconds_only(self):
print(etree.tostring(element, pretty_print=True))
assert element[0].text == answer
- data = element.find('{%s}howlong' % gg.get_namespace()).text
+ data = element.find("{%s}howlong" % gg.get_namespace()).text
self.assertEqual(data, answer)
s1 = XmlDocument().from_element(None, SomeBlob, element)
assert s1.howlong.total_seconds() == gg.howlong.total_seconds()
def test_duration_xml_duration(self):
- dur = datetime.timedelta(days=5 + 30 + 365, hours=1, minutes=1,
- seconds=12, microseconds=8e5)
+ dur = datetime.timedelta(
+ days=5 + 30 + 365, hours=1, minutes=1, seconds=12, microseconds=8e5
+ )
- str1 = 'P400DT3672.8S'
- str2 = 'P1Y1M5DT1H1M12.8S'
+ str1 = "P400DT3672.8S"
+ str2 = "P1Y1M5DT1H1M12.8S"
self.assertEqual(dur, ProtocolBase().from_unicode(Duration, str1))
self.assertEqual(dur, ProtocolBase().from_unicode(Duration, str2))
- self.assertEqual(dur, ProtocolBase().from_unicode(Duration,
- ProtocolBase().to_unicode(Duration, dur)))
+ self.assertEqual(
+ dur,
+ ProtocolBase().from_unicode(
+ Duration, ProtocolBase().to_unicode(Duration, dur)
+ ),
+ )
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/multipython/model/test_complex.py b/spyne/test/multipython/model/test_complex.py
index 9aa8d1cb2..9cf9a61dc 100644
--- a/spyne/test/multipython/model/test_complex.py
+++ b/spyne/test/multipython/model/test_complex.py
@@ -22,13 +22,11 @@
import unittest
-from spyne.model.complex import (ComplexModel, ComplexModelMeta,
- ComplexModelBase, Array)
-from spyne.model.primitive import Unicode, Integer, String
-from spyne.util.six import add_metaclass
+from spyne.model.complex import Array, ComplexModel, ComplexModelBase, ComplexModelMeta
+from spyne.model.primitive import Integer, String, Unicode
-class DeclareOrder_declare(ComplexModel.customize(declare_order='declared')):
+class DeclareOrder_declare(ComplexModel.customize(declare_order="declared")):
field3 = Integer
field1 = Integer
field2 = Integer
@@ -38,24 +36,24 @@ class MyComplexModelMeta(ComplexModelMeta):
"""Custom complex model metaclass."""
def __new__(mcs, name, bases, attrs):
- attrs['new_field'] = Unicode
- attrs['field1'] = Unicode
- new_cls = super(MyComplexModelMeta, mcs).__new__(mcs, name, bases,
- attrs)
+ attrs["new_field"] = Unicode
+ attrs["field1"] = Unicode
+ new_cls = super(MyComplexModelMeta, mcs).__new__(mcs, name, bases, attrs)
return new_cls
-@add_metaclass(MyComplexModelMeta)
-class MyComplexModel(ComplexModelBase):
+class MyComplexModel(ComplexModelBase, metaclass=MyComplexModelMeta):
"""Custom complex model class."""
+
class Attributes(ComplexModelBase.Attributes):
- declare_order = 'declared'
+ declare_order = "declared"
class MyModelWithDeclaredOrder(MyComplexModel):
"""Test model for complex model with custom metaclass."""
+
class Attributes(MyComplexModel.Attributes):
- declare_order = 'declared'
+ declare_order = "declared"
field3 = Integer
field1 = Integer
@@ -66,71 +64,75 @@ class TestComplexModel(unittest.TestCase):
def test_add_field(self):
class C(ComplexModel):
u = Unicode
- C.append_field('i', Integer)
- assert C._type_info['i'] is Integer
+
+ C.append_field("i", Integer)
+ assert C._type_info["i"] is Integer
def test_insert_field(self):
class C(ComplexModel):
u = Unicode
- C.insert_field(0, 'i', Integer)
- assert C._type_info.keys() == ['i', 'u']
+
+ C.insert_field(0, "i", Integer)
+ assert C._type_info.keys() == ["i", "u"]
def test_variants(self):
class C(ComplexModel):
u = Unicode
+
CC = C.customize(child_attrs=dict(u=dict(min_len=5)))
print(dict(C.Attributes._variants.items()))
- r, = C.Attributes._variants
+ (r,) = C.Attributes._variants
assert r is CC
assert CC.Attributes.parent_variant is C
- C.append_field('i', Integer)
- assert C._type_info['i'] is Integer
- assert CC._type_info['i'] is Integer
+ C.append_field("i", Integer)
+ assert C._type_info["i"] is Integer
+ assert CC._type_info["i"] is Integer
def test_child_customization(self):
class C(ComplexModel):
u = Unicode
+
CC = C.customize(child_attrs=dict(u=dict(min_len=5)))
- assert CC._type_info['u'].Attributes.min_len == 5
- assert C._type_info['u'].Attributes.min_len != 5
+ assert CC._type_info["u"].Attributes.min_len == 5
+ assert C._type_info["u"].Attributes.min_len != 5
def test_array_customization(self):
CC = Array(Unicode).customize(
- serializer_attrs=dict(min_len=5), punks='roll',
+ serializer_attrs=dict(min_len=5),
+ punks="roll",
)
- assert CC.Attributes.punks == 'roll'
+ assert CC.Attributes.punks == "roll"
assert CC._type_info[0].Attributes.min_len == 5
def test_array_customization_complex(self):
class C(ComplexModel):
u = Unicode
- CC = Array(C).customize(
- punks='roll',
- serializer_attrs=dict(bidik=True)
- )
- assert CC.Attributes.punks == 'roll'
+ CC = Array(C).customize(punks="roll", serializer_attrs=dict(bidik=True))
+ assert CC.Attributes.punks == "roll"
assert CC._type_info[0].Attributes.bidik == True
def test_delayed_child_customization_append(self):
class C(ComplexModel):
u = Unicode
+
CC = C.customize(child_attrs=dict(i=dict(ge=5)))
- CC.append_field('i', Integer)
- assert CC._type_info['i'].Attributes.ge == 5
- assert not 'i' in C._type_info
+ CC.append_field("i", Integer)
+ assert CC._type_info["i"].Attributes.ge == 5
+ assert not "i" in C._type_info
def test_delayed_child_customization_insert(self):
class C(ComplexModel):
u = Unicode
+
CC = C.customize(child_attrs=dict(i=dict(ge=5)))
- CC.insert_field(1, 'i', Integer)
- assert CC._type_info['i'].Attributes.ge == 5
- assert not 'i' in C._type_info
+ CC.insert_field(1, "i", Integer)
+ assert CC._type_info["i"].Attributes.ge == 5
+ assert not "i" in C._type_info
def test_array_member_name(self):
print(Array(String, member_name="punk")._type_info)
- assert 'punk' in Array(String, member_name="punk")._type_info
+ assert "punk" in Array(String, member_name="punk")._type_info
def test_customize(self):
class Base(ComplexModel):
@@ -140,7 +142,7 @@ class Attributes(ComplexModel.Attributes):
Base2 = Base.customize(prop1=4)
- self.assertNotEquals(Base.Attributes.prop1, Base2.Attributes.prop1)
+ self.assertNotEqual(Base.Attributes.prop1, Base2.Attributes.prop1)
self.assertEqual(Base.Attributes.prop2, Base2.Attributes.prop2)
class Derived(Base):
@@ -156,7 +158,7 @@ class Attributes(Base.Attributes):
self.assertEqual(Derived.Attributes.prop1, 3)
self.assertEqual(Derived2.Attributes.prop1, 5)
- self.assertNotEquals(Derived.Attributes.prop3, Derived2.Attributes.prop3)
+ self.assertNotEqual(Derived.Attributes.prop3, Derived2.Attributes.prop3)
self.assertEqual(Derived.Attributes.prop4, Derived2.Attributes.prop4)
Derived3 = Derived.customize(prop3=12)
@@ -164,16 +166,20 @@ class Attributes(Base.Attributes):
# changes made to bases propagate, unless overridden
self.assertEqual(Derived.Attributes.prop1, Base.Attributes.prop1)
- self.assertNotEquals(Derived2.Attributes.prop1, Base.Attributes.prop1)
+ self.assertNotEqual(Derived2.Attributes.prop1, Base.Attributes.prop1)
self.assertEqual(Derived3.Attributes.prop1, Base.Attributes.prop1)
def test_declare_order(self):
- self.assertEqual(["field3", "field1", "field2"],
- list(DeclareOrder_declare._type_info))
- self.assertEqual(["field3", "field1", "field2", "new_field"],
- list(MyModelWithDeclaredOrder._type_info))
+ self.assertEqual(
+ ["field3", "field1", "field2"], list(DeclareOrder_declare._type_info)
+ )
+ self.assertEqual(
+ ["field3", "field1", "field2", "new_field"],
+ list(MyModelWithDeclaredOrder._type_info),
+ )
-if __name__ == '__main__':
+if __name__ == "__main__":
import sys
+
sys.exit(unittest.main())
diff --git a/spyne/test/protocol/__init__.py b/spyne/test/protocol/__init__.py
index 725080664..898794071 100644
--- a/spyne/test/protocol/__init__.py
+++ b/spyne/test/protocol/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
diff --git a/spyne/test/protocol/_test_dictdoc.py b/spyne/test/protocol/_test_dictdoc.py
index 7e4af3dfa..2ccc39888 100644
--- a/spyne/test/protocol/_test_dictdoc.py
+++ b/spyne/test/protocol/_test_dictdoc.py
@@ -25,63 +25,58 @@
logger = logging.getLogger(__name__)
+import decimal
import unittest
-
import uuid
+
import pytz
-import decimal
-from spyne.util import six
+
from spyne.util.dictdoc import get_object_as_dict
-if not six.PY2:
- long = int
+long = int
-from datetime import datetime
-from datetime import date
-from datetime import time
-from datetime import timedelta
+from datetime import date, datetime, time, timedelta
import lxml.etree
import lxml.html
-
from lxml.builder import E
-from spyne import MethodContext, Ignored
-from spyne.service import Service
-from spyne.server import ServerBase
+from spyne import Ignored, MethodContext
from spyne.application import Application
-from spyne.decorator import srpc, rpc
+from spyne.decorator import rpc, srpc
from spyne.error import ValidationError
-from spyne.model.binary import binary_encoding_handlers, File
-from spyne.model.complex import ComplexModel
-from spyne.model.complex import Iterable
+from spyne.model.binary import ByteArray, File, binary_encoding_handlers
+from spyne.model.complex import ComplexModel, Iterable
from spyne.model.fault import Fault
+from spyne.model.primitive import (
+ AnyDict,
+ AnyHtml,
+ AnyUri,
+ AnyXml,
+ Boolean,
+ Date,
+ DateTime,
+ Decimal,
+ Double,
+ Duration,
+ ImageUri,
+ Integer,
+ Integer8,
+ Line,
+ Mandatory,
+ MultiLine,
+ MultiPoint,
+ MultiPolygon,
+ Point,
+ Polygon,
+ String,
+ Time,
+ Unicode,
+ Uuid,
+)
from spyne.protocol import ProtocolBase
-from spyne.model.binary import ByteArray
-from spyne.model.primitive import Decimal
-from spyne.model.primitive import Integer
-from spyne.model.primitive import String
-from spyne.model.primitive import DateTime
-from spyne.model.primitive import Mandatory
-from spyne.model.primitive import AnyXml
-from spyne.model.primitive import AnyHtml
-from spyne.model.primitive import AnyDict
-from spyne.model.primitive import Unicode
-from spyne.model.primitive import AnyUri
-from spyne.model.primitive import ImageUri
-from spyne.model.primitive import Double
-from spyne.model.primitive import Integer8
-from spyne.model.primitive import Time
-from spyne.model.primitive import Date
-from spyne.model.primitive import Duration
-from spyne.model.primitive import Boolean
-from spyne.model.primitive import Uuid
-from spyne.model.primitive import Point
-from spyne.model.primitive import Line
-from spyne.model.primitive import Polygon
-from spyne.model.primitive import MultiPoint
-from spyne.model.primitive import MultiLine
-from spyne.model.primitive import MultiPolygon
+from spyne.server import ServerBase
+from spyne.service import Service
def _unbyte(d):
@@ -91,7 +86,7 @@ def _unbyte(d):
for k, v in list(d.items()):
if isinstance(k, bytes):
del d[k]
- d[k.decode('utf8')] = v
+ d[k.decode("utf8")] = v
if isinstance(v, dict):
_unbyte(v)
@@ -113,7 +108,7 @@ def _unbyte(d):
elif isinstance(v, bytes):
try:
- d[k] = v.decode('utf8')
+ d[k] = v.decode("utf8")
except UnicodeDecodeError:
d[k] = v
@@ -124,28 +119,41 @@ def TDry(serializer, _DictDocumentChild, dumps_kwargs=None):
if not dumps_kwargs:
dumps_kwargs = {}
- def _dry_me(services, d, ignore_wrappers=False, complex_as=dict,
- just_ctx=False, just_in_object=False, validator=None,
- polymorphic=False):
-
- app = Application(services, 'tns',
- in_protocol=_DictDocumentChild(
- ignore_wrappers=ignore_wrappers, complex_as=complex_as,
- polymorphic=polymorphic, validator=validator,
- ),
- out_protocol=_DictDocumentChild(
- ignore_wrappers=ignore_wrappers, complex_as=complex_as,
- polymorphic=polymorphic),
- )
+ def _dry_me(
+ services,
+ d,
+ ignore_wrappers=False,
+ complex_as=dict,
+ just_ctx=False,
+ just_in_object=False,
+ validator=None,
+ polymorphic=False,
+ ):
+
+ app = Application(
+ services,
+ "tns",
+ in_protocol=_DictDocumentChild(
+ ignore_wrappers=ignore_wrappers,
+ complex_as=complex_as,
+ polymorphic=polymorphic,
+ validator=validator,
+ ),
+ out_protocol=_DictDocumentChild(
+ ignore_wrappers=ignore_wrappers,
+ complex_as=complex_as,
+ polymorphic=polymorphic,
+ ),
+ )
server = ServerBase(app)
initial_ctx = MethodContext(server, MethodContext.SERVER)
in_string = serializer.dumps(d, **dumps_kwargs)
if not isinstance(in_string, bytes):
- in_string = in_string.encode('utf8')
+ in_string = in_string.encode("utf8")
initial_ctx.in_string = [in_string]
- ctx, = server.generate_contexts(initial_ctx, in_string_charset='utf8')
+ (ctx,) = server.generate_contexts(initial_ctx, in_string_charset="utf8")
if not just_ctx:
server.get_in_object(ctx)
if not just_in_object:
@@ -153,10 +161,17 @@ def _dry_me(services, d, ignore_wrappers=False, complex_as=dict,
server.get_out_string(ctx)
return ctx
+
return _dry_me
-def TDictDocumentTest(serializer, _DictDocumentChild, dumps_kwargs=None,
- loads_kwargs=None, convert_dict=None):
+
+def TDictDocumentTest(
+ serializer,
+ _DictDocumentChild,
+ dumps_kwargs=None,
+ loads_kwargs=None,
+ convert_dict=None,
+):
if not dumps_kwargs:
dumps_kwargs = {}
if not loads_kwargs:
@@ -175,7 +190,9 @@ def loads(self, o):
try:
return _unbyte(serializer.loads(o, **loads_kwargs))
except TypeError:
- return _unbyte(serializer.loads(o, Loader=yaml.FullLoader, **loads_kwargs))
+ return _unbyte(
+ serializer.loads(o, Loader=yaml.FullLoader, **loads_kwargs)
+ )
def test_complex_with_only_primitive_fields(self):
class SomeComplexModel(ComplexModel):
@@ -185,11 +202,11 @@ class SomeComplexModel(ComplexModel):
class SomeService(Service):
@srpc(SomeComplexModel, _returns=SomeComplexModel)
def some_call(scm):
- return SomeComplexModel(i=5, s='5x')
+ return SomeComplexModel(i=5, s="5x")
- ctx = _dry_me([SomeService], {"some_call":[]})
+ ctx = _dry_me([SomeService], {"some_call": []})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
s = s["some_callResponse"]["some_callResult"]["SomeComplexModel"]
assert s["i"] == 5
@@ -210,49 +227,62 @@ class SomeService(Service):
def some_call(ccm):
return CCM(c=ccm.c, i=ccm.i, s=ccm.s)
- ctx = _dry_me([SomeService], {"some_call":
- {"ccm": {"CCM":{
- "c":{"CM":{"i":3, "s": "3x"}},
- "i":4,
- "s": "4x",
- }}}
- })
+ ctx = _dry_me(
+ [SomeService],
+ {
+ "some_call": {
+ "ccm": {
+ "CCM": {
+ "c": {"CM": {"i": 3, "s": "3x"}},
+ "i": 4,
+ "s": "4x",
+ }
+ }
+ }
+ },
+ )
- ret = self.loads(b''.join(ctx.out_string))
+ ret = self.loads(b"".join(ctx.out_string))
print(ret)
- d = ret['some_callResponse']['some_callResult']['CCM']
- assert d['i'] == 4
- assert d['s'] in ('4x', b'4x')
- assert d['c']['CM']['i'] == 3
- assert d['c']['CM']['s'] in ('3x', b'3x')
+ d = ret["some_callResponse"]["some_callResult"]["CCM"]
+ assert d["i"] == 4
+ assert d["s"] in ("4x", b"4x")
+ assert d["c"]["CM"]["i"] == 3
+ assert d["c"]["CM"]["s"] in ("3x", b"3x")
def test_multiple_list(self):
class SomeService(Service):
- @srpc(Unicode(max_occurs=decimal.Decimal('inf')),
- _returns=Unicode(max_occurs=decimal.Decimal('inf')))
+ @srpc(
+ Unicode(max_occurs=decimal.Decimal("inf")),
+ _returns=Unicode(max_occurs=decimal.Decimal("inf")),
+ )
def some_call(s):
return s
- ctx = _dry_me([SomeService], {"some_call":[["a","b"]]})
+ ctx = _dry_me([SomeService], {"some_call": [["a", "b"]]})
- data = b''.join(ctx.out_string)
+ data = b"".join(ctx.out_string)
print(data)
- assert self.loads(data) == \
- {"some_callResponse": {"some_callResult": ("a", "b")}}
+ assert self.loads(data) == {
+ "some_callResponse": {"some_callResult": ("a", "b")}
+ }
def test_multiple_dict(self):
class SomeService(Service):
- @srpc(Unicode(max_occurs=decimal.Decimal('inf')),
- _returns=Unicode(max_occurs=decimal.Decimal('inf')))
+ @srpc(
+ Unicode(max_occurs=decimal.Decimal("inf")),
+ _returns=Unicode(max_occurs=decimal.Decimal("inf")),
+ )
def some_call(s):
return s
- ctx = _dry_me([SomeService], {"some_call":{"s":["a","b"]}})
+ ctx = _dry_me([SomeService], {"some_call": {"s": ["a", "b"]}})
- assert self.loads(b''.join(ctx.out_string)) == \
- {"some_callResponse": {"some_callResult": ("a", "b")}}
+ assert self.loads(b"".join(ctx.out_string)) == {
+ "some_callResponse": {"some_callResult": ("a", "b")}
+ }
def test_multiple_dict_array(self):
class SomeService(Service):
@@ -260,10 +290,11 @@ class SomeService(Service):
def some_call(s):
return s
- ctx = _dry_me([SomeService], {"some_call":{"s":["a","b"]}})
+ ctx = _dry_me([SomeService], {"some_call": {"s": ["a", "b"]}})
- assert self.loads(b''.join(ctx.out_string)) == \
- {"some_callResponse": {"some_callResult": ("a", "b")}}
+ assert self.loads(b"".join(ctx.out_string)) == {
+ "some_callResponse": {"some_callResult": ("a", "b")}
+ }
def test_multiple_dict_complex_array(self):
class CM(ComplexModel):
@@ -283,61 +314,87 @@ class SomeService(Service):
def some_call(ecm):
return ecm
- ctx = _dry_me([SomeService], {
- "some_call": {"ecm": [{"ECM": {
- "c": {"CM":{"i":3, "s": "3x"}},
- "i":4,
- "s": "4x",
- "d": "2011-12-13T14:15:16Z"
- }}]
- }})
+ ctx = _dry_me(
+ [SomeService],
+ {
+ "some_call": {
+ "ecm": [
+ {
+ "ECM": {
+ "c": {"CM": {"i": 3, "s": "3x"}},
+ "i": 4,
+ "s": "4x",
+ "d": "2011-12-13T14:15:16Z",
+ }
+ }
+ ]
+ }
+ },
+ )
print(ctx.in_object)
- ret = self.loads(b''.join(ctx.out_string))
+ ret = self.loads(b"".join(ctx.out_string))
print(ret)
- assert ret["some_callResponse"]['some_callResult']
- assert ret["some_callResponse"]['some_callResult'][0]
- assert ret["some_callResponse"]['some_callResult'][0]["ECM"]["c"]
- assert ret["some_callResponse"]['some_callResult'][0]["ECM"]["c"]["CM"]["i"] == 3
- assert ret["some_callResponse"]['some_callResult'][0]["ECM"]["c"]["CM"]["s"] in ("3x", b"3x")
- assert ret["some_callResponse"]['some_callResult'][0]["ECM"]["i"] == 4
- assert ret["some_callResponse"]['some_callResult'][0]["ECM"]["s"] in ("4x", b"4x")
- assert ret["some_callResponse"]['some_callResult'][0]["ECM"]["d"] == "2011-12-13T14:15:16+00:00"
+ assert ret["some_callResponse"]["some_callResult"]
+ assert ret["some_callResponse"]["some_callResult"][0]
+ assert ret["some_callResponse"]["some_callResult"][0]["ECM"]["c"]
+ assert (
+ ret["some_callResponse"]["some_callResult"][0]["ECM"]["c"]["CM"]["i"]
+ == 3
+ )
+ assert ret["some_callResponse"]["some_callResult"][0]["ECM"]["c"]["CM"][
+ "s"
+ ] in ("3x", b"3x")
+ assert ret["some_callResponse"]["some_callResult"][0]["ECM"]["i"] == 4
+ assert ret["some_callResponse"]["some_callResult"][0]["ECM"]["s"] in (
+ "4x",
+ b"4x",
+ )
+ assert (
+ ret["some_callResponse"]["some_callResult"][0]["ECM"]["d"]
+ == "2011-12-13T14:15:16+00:00"
+ )
def test_invalid_request(self):
class SomeService(Service):
@srpc(Integer, String, DateTime)
- def yay(i,s,d):
- print(i,s,d)
+ def yay(i, s, d):
+ print(i, s, d)
- ctx = _dry_me([SomeService], {"some_call": {"yay": []}},
- just_in_object=True)
+ ctx = _dry_me(
+ [SomeService], {"some_call": {"yay": []}}, just_in_object=True
+ )
print(ctx.in_error)
- assert ctx.in_error.faultcode == 'Client.ResourceNotFound'
+ assert ctx.in_error.faultcode == "Client.ResourceNotFound"
def test_invalid_string(self):
class SomeService(Service):
@srpc(Integer, String, DateTime)
- def yay(i,s,d):
+ def yay(i, s, d):
print(i, s, d)
- ctx = _dry_me([SomeService], {"yay": {"s": 1}}, validator='soft',
- just_in_object=True)
+ ctx = _dry_me(
+ [SomeService], {"yay": {"s": 1}}, validator="soft", just_in_object=True
+ )
- assert ctx.in_error.faultcode == 'Client.ValidationError'
+ assert ctx.in_error.faultcode == "Client.ValidationError"
def test_invalid_number(self):
class SomeService(Service):
@srpc(Integer, String, DateTime)
- def yay(i,s,d):
- print(i,s,d)
+ def yay(i, s, d):
+ print(i, s, d)
- ctx = _dry_me([SomeService], {"yay": ["s", "B"]}, validator='soft',
- just_in_object=True)
+ ctx = _dry_me(
+ [SomeService],
+ {"yay": ["s", "B"]},
+ validator="soft",
+ just_in_object=True,
+ )
- assert ctx.in_error.faultcode == 'Client.ValidationError'
+ assert ctx.in_error.faultcode == "Client.ValidationError"
def test_missing_value(self):
class SomeService(Service):
@@ -345,23 +402,28 @@ class SomeService(Service):
def yay(i, s, d):
print(i, s, d)
- ctx = _dry_me([SomeService], {"yay": [1, "B"]}, validator='soft',
- just_in_object=True)
+ ctx = _dry_me(
+ [SomeService], {"yay": [1, "B"]}, validator="soft", just_in_object=True
+ )
print(ctx.in_error.faultstring)
- assert ctx.in_error.faultcode == 'Client.ValidationError'
+ assert ctx.in_error.faultcode == "Client.ValidationError"
assert ctx.in_error.faultstring.endswith("at least 1 times.")
def test_invalid_datetime(self):
class SomeService(Service):
@srpc(Integer, String, Mandatory.DateTime)
- def yay(i,s,d):
- print(i,s,d)
+ def yay(i, s, d):
+ print(i, s, d)
- ctx = _dry_me([SomeService],{"yay": {"d":"a2011"}},validator='soft',
- just_in_object=True)
+ ctx = _dry_me(
+ [SomeService],
+ {"yay": {"d": "a2011"}},
+ validator="soft",
+ just_in_object=True,
+ )
- assert ctx.in_error.faultcode == 'Client.ValidationError'
+ assert ctx.in_error.faultcode == "Client.ValidationError"
def test_fault_to_dict(self):
class SomeService(Service):
@@ -369,7 +431,7 @@ class SomeService(Service):
def some_call():
raise Fault()
- _dry_me([SomeService], {"some_call":[]})
+ _dry_me([SomeService], {"some_call": []})
def test_prune_none_and_optional(self):
class SomeObject(ComplexModel):
@@ -381,16 +443,18 @@ class SomeService(Service):
def some_call():
return SomeObject()
- ctx = _dry_me([SomeService], {"some_call":[]})
+ ctx = _dry_me([SomeService], {"some_call": []})
- ret = self.loads(b''.join(ctx.out_string))
+ ret = self.loads(b"".join(ctx.out_string))
- assert ret == {"some_callResponse": {'some_callResult':
- {'SomeObject': {'s': None}}}}
+ assert ret == {
+ "some_callResponse": {"some_callResult": {"SomeObject": {"s": None}}}
+ }
def test_any_xml(self):
- d = lxml.etree.tostring(E('{ns1}x', E('{ns2}Y', "some data")),
- encoding='unicode')
+ d = lxml.etree.tostring(
+ E("{ns1}x", E("{ns2}Y", "some data")), encoding="unicode"
+ )
class SomeService(Service):
@srpc(AnyXml, _returns=AnyXml)
@@ -400,17 +464,16 @@ def some_call(p):
assert type(p) == lxml.etree._Element
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_any_html(self):
- d = lxml.html.tostring(E('div', E('span', "something")),
- encoding='unicode')
+ d = lxml.html.tostring(E("div", E("span", "something")), encoding="unicode")
class SomeService(Service):
@srpc(AnyHtml, _returns=AnyHtml)
@@ -422,7 +485,7 @@ def some_call(p):
ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
@@ -430,7 +493,7 @@ def some_call(p):
assert s == d
def test_any_dict(self):
- d = {'helo': 213, 'data': {'nested': [12, 0.3]}}
+ d = {"helo": 213, "data": {"nested": [12, 0.3]}}
class SomeService(Service):
@srpc(AnyDict, _returns=AnyDict)
@@ -440,9 +503,9 @@ def some_call(p):
assert type(p) == dict
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = b''.join(ctx.out_string)
+ s = b"".join(ctx.out_string)
d = self.dumps({"some_callResponse": {"some_callResult": d}})
print(s)
@@ -450,64 +513,64 @@ def some_call(p):
assert self.loads(s) == self.loads(d)
def test_unicode(self):
- d = u'some string'
+ d = "some string"
class SomeService(Service):
@srpc(Unicode, _returns=Unicode)
def some_call(p):
print(p)
print(type(p))
- assert type(p) == six.text_type
+ assert type(p) == str
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_any_uri(self):
- d = 'http://example.com/?asd=b12&df=aa#tag'
+ d = "http://example.com/?asd=b12&df=aa#tag"
class SomeService(Service):
@srpc(AnyUri, _returns=AnyUri)
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_image_uri(self):
- d = 'http://example.com/funny.gif'
+ d = "http://example.com/funny.gif"
class SomeService(Service):
@srpc(ImageUri, _returns=ImageUri)
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_decimal(self):
- d = decimal.Decimal('1e100')
+ d = decimal.Decimal("1e100")
if _DictDocumentChild._decimal_as_string:
d = str(d)
@@ -521,7 +584,7 @@ def some_call(p):
ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
@@ -538,9 +601,9 @@ def some_call(p):
assert type(p) == float
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
@@ -557,16 +620,16 @@ def some_call(p):
assert type(p) == int
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_integer_way_small(self):
- d = -1<<1000
+ d = -1 << 1000
if _DictDocumentChild._huge_numbers_as_string:
d = str(d)
@@ -578,9 +641,9 @@ def some_call(p):
assert type(p) == long
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
@@ -588,7 +651,7 @@ def some_call(p):
assert s == d
def test_integer_way_big(self):
- d = 1<<1000
+ d = 1 << 1000
if _DictDocumentChild._huge_numbers_as_string:
d = str(d)
@@ -600,9 +663,9 @@ def some_call(p):
assert type(p) == long
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
@@ -620,9 +683,9 @@ def some_call(p):
assert p.isoformat() == d
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
@@ -646,14 +709,14 @@ def some_call_dt():
return vdt
ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
rd = {"some_callResponse": {"some_callResult": d}}
print(s)
print(rd)
assert s == rd
ctx = _dry_me([SomeService], {"some_call_dt": []})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
rd = {"some_call_dtResponse": {"some_call_dtResult": d}}
print(s)
print(rd)
@@ -671,9 +734,9 @@ def some_call(p):
assert p.replace(tzinfo=None).isoformat() == d
return p
- ctx = _dry_me([SomeService], {"some_call":[d]}, validator='soft')
+ ctx = _dry_me([SomeService], {"some_call": [d]}, validator="soft")
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
@@ -683,7 +746,10 @@ def test_datetime_tz(self):
d = datetime(2010, 9, 8, 7, 6, 5, tzinfo=pytz.utc).isoformat()
class SomeService(Service):
- @srpc(DateTime, _returns=DateTime(ge=datetime(2010,1,1,tzinfo=pytz.utc)))
+ @srpc(
+ DateTime,
+ _returns=DateTime(ge=datetime(2010, 1, 1, tzinfo=pytz.utc)),
+ )
def some_call(p):
print(p)
print(type(p))
@@ -691,9 +757,9 @@ def some_call(p):
assert p.isoformat() == d
return p
- ctx = _dry_me([SomeService], {"some_call":[d]}, validator='soft')
+ ctx = _dry_me([SomeService], {"some_call": [d]}, validator="soft")
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
@@ -710,9 +776,9 @@ def some_call(p):
assert type(p) == timedelta
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
@@ -729,16 +795,16 @@ def some_call(p):
assert type(p) == bool
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_uuid(self):
- d = '7d2a6330-eb64-4900-8a10-38ebef415e9d'
+ d = "7d2a6330-eb64-4900-8a10-38ebef415e9d"
class SomeService(Service):
@srpc(Uuid, _returns=Uuid)
@@ -748,239 +814,241 @@ def some_call(p):
assert type(p) == uuid.UUID
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_point2d(self):
- d = 'POINT(1 2)'
+ d = "POINT(1 2)"
class SomeService(Service):
@srpc(Point, _returns=Point)
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_point3d(self):
- d = 'POINT(1 2 3)'
+ d = "POINT(1 2 3)"
class SomeService(Service):
@srpc(Point, _returns=Point)
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_line2d(self):
- d = 'LINESTRING(1 2, 3 4)'
+ d = "LINESTRING(1 2, 3 4)"
class SomeService(Service):
@srpc(Line, _returns=Line)
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_line3d(self):
- d = 'LINESTRING(1 2 3, 4 5 6)'
+ d = "LINESTRING(1 2 3, 4 5 6)"
class SomeService(Service):
@srpc(Line, _returns=Line)
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_polygon2d(self):
- d = 'POLYGON((1 1, 1 2, 2 2, 2 1, 1 1))'
+ d = "POLYGON((1 1, 1 2, 2 2, 2 1, 1 1))"
class SomeService(Service):
@srpc(Polygon(2), _returns=Polygon(2))
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_polygon3d(self):
- d = 'POLYGON((1 1 0, 1 2 0, 2 2 0, 2 1 0, 1 1 0))'
+ d = "POLYGON((1 1 0, 1 2 0, 2 2 0, 2 1 0, 1 1 0))"
class SomeService(Service):
@srpc(Polygon(3), _returns=Polygon(3))
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_multipoint2d(self):
- d = 'MULTIPOINT ((10 40), (40 30), (20 20), (30 10))'
+ d = "MULTIPOINT ((10 40), (40 30), (20 20), (30 10))"
class SomeService(Service):
@srpc(MultiPoint(2), _returns=MultiPoint(2))
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_multipoint3d(self):
- d = 'MULTIPOINT (10 40 30, 40 30 10,)'
+ d = "MULTIPOINT (10 40 30, 40 30 10,)"
class SomeService(Service):
@srpc(MultiPoint(3), _returns=MultiPoint(3))
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_multiline2d(self):
- d = 'MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))'
+ d = "MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))"
class SomeService(Service):
@srpc(MultiLine(2), _returns=MultiLine(2))
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_multiline3d(self):
- d = 'MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))'
+ d = "MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))"
class SomeService(Service):
@srpc(MultiLine(3), _returns=MultiLine(3))
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_multipolygon2d(self):
- d = 'MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))'
+ d = "MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))"
class SomeService(Service):
@srpc(MultiPolygon(2), _returns=MultiPolygon(2))
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
assert s == d
def test_multipolygon3d(self):
- d = 'MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),' \
- '((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),' \
- '(30 20, 20 25, 20 15, 30 20)))'
+ d = (
+ "MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),"
+ "((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),"
+ "(30 20, 20 25, 20 15, 30 20)))"
+ )
class SomeService(Service):
@srpc(MultiPolygon(3), _returns=MultiPolygon(3))
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return p
- ctx = _dry_me([SomeService], {"some_call":[d]})
+ ctx = _dry_me([SomeService], {"some_call": [d]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": d}}
print(s)
print(d)
@@ -992,9 +1060,9 @@ class SomeService(Service):
def some_call():
return iter(range(1000))
- ctx = _dry_me([SomeService], {"some_call":[]})
+ ctx = _dry_me([SomeService], {"some_call": []})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": tuple(range(1000))}}
print(s)
print(d)
@@ -1004,10 +1072,10 @@ def test_bytearray(self):
dbe = _DictDocumentChild.default_binary_encoding
beh = binary_encoding_handlers[dbe]
- data = bytes(bytearray(range(0xff)))
+ data = bytes(bytearray(range(0xFF)))
encoded_data = beh([data])
if _DictDocumentChild.text_based:
- encoded_data = encoded_data.decode('latin1')
+ encoded_data = encoded_data.decode("latin1")
class SomeService(Service):
@srpc(ByteArray, _returns=ByteArray)
@@ -1020,7 +1088,7 @@ def some_call(ba):
ctx = _dry_me([SomeService], {"some_call": [encoded_data]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": encoded_data}}
print(repr(s))
@@ -1034,10 +1102,10 @@ def test_file_data(self):
dbe = _DictDocumentChild.default_binary_encoding
beh = binary_encoding_handlers[dbe]
- data = bytes(bytearray(range(0xff)))
+ data = bytes(bytearray(range(0xFF)))
encoded_data = beh([data])
if _DictDocumentChild.text_based:
- encoded_data = encoded_data.decode('latin1')
+ encoded_data = encoded_data.decode("latin1")
class SomeService(Service):
@srpc(File, _returns=File)
@@ -1051,7 +1119,7 @@ def some_call(p):
# we put the encoded data in the list of arguments.
ctx = _dry_me([SomeService], {"some_call": [encoded_data]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {"some_callResult": encoded_data}}
print(s)
@@ -1065,14 +1133,14 @@ def test_file_value(self):
# Prepare data
v = File.Value(
- name='some_file.bin',
- type='application/octet-stream',
+ name="some_file.bin",
+ type="application/octet-stream",
)
- file_data = bytes(bytearray(range(0xff)))
+ file_data = bytes(bytearray(range(0xFF)))
v.data = (file_data,)
beh([file_data])
if _DictDocumentChild.text_based:
- test_data = beh(v.data).decode('latin1')
+ test_data = beh(v.data).decode("latin1")
else:
test_data = beh(v.data)
@@ -1089,15 +1157,22 @@ def some_call(p):
assert p.name == v.name
return p
- d = get_object_as_dict(v, File, protocol=_DictDocumentChild,
- ignore_wrappers=False)
- ctx = _dry_me([SomeService], {"some_call": {'p': d}})
- s = b''.join(ctx.out_string)
- d = self.dumps({"some_callResponse": {"some_callResult": {
- 'name': v.name,
- 'type': v.type,
- 'data': test_data,
- }}})
+ d = get_object_as_dict(
+ v, File, protocol=_DictDocumentChild, ignore_wrappers=False
+ )
+ ctx = _dry_me([SomeService], {"some_call": {"p": d}})
+ s = b"".join(ctx.out_string)
+ d = self.dumps(
+ {
+ "some_callResponse": {
+ "some_callResult": {
+ "name": v.name,
+ "type": v.type,
+ "data": test_data,
+ }
+ }
+ }
+ )
print(self.loads(s))
print(self.loads(d))
@@ -1110,12 +1185,12 @@ class SomeService(Service):
def some_call(p):
print(p)
print(type(p))
- assert isinstance(p, six.string_types)
+ assert isinstance(p, str)
return Ignored("aaa", b=1, c=2)
ctx = _dry_me([SomeService], {"some_call": ["some string"]})
- s = self.loads(b''.join(ctx.out_string))
+ s = self.loads(b"".join(ctx.out_string))
d = {"some_callResponse": {}}
assert s == d
@@ -1126,7 +1201,7 @@ def some_call(p):
pass
try:
- _dry_me([SomeService], {"some_call": []}, validator='soft')
+ _dry_me([SomeService], {"some_call": []}, validator="soft")
except ValidationError:
pass
else:
@@ -1139,8 +1214,7 @@ def some_call(p):
pass
try:
- _dry_me([SomeService], {"some_call": [None]},
- validator='soft')
+ _dry_me([SomeService], {"some_call": [None]}, validator="soft")
except ValidationError:
pass
@@ -1154,8 +1228,7 @@ def some_call(p):
pass
try:
- _dry_me([SomeService], {"some_call": ["duduk"]},
- validator='soft')
+ _dry_me([SomeService], {"some_call": ["duduk"]}, validator="soft")
except ValidationError as e:
print(e)
pass
@@ -1170,8 +1243,7 @@ def some_call(p):
pass
try:
- _dry_me([SomeService], {"some_call": [10]},
- validator='soft')
+ _dry_me([SomeService], {"some_call": [10]}, validator="soft")
except ValidationError:
pass
@@ -1185,8 +1257,7 @@ def some_call(p):
pass
try:
- _dry_me([SomeService], {"some_call": [-129]},
- validator='soft')
+ _dry_me([SomeService], {"some_call": [-129]}, validator="soft")
except ValidationError:
pass
@@ -1200,7 +1271,7 @@ def some_call(p):
pass
try:
- _dry_me([SomeService], {"some_call": [1.2]}, validator='soft')
+ _dry_me([SomeService], {"some_call": [1.2]}, validator="soft")
except ValidationError:
pass
@@ -1219,22 +1290,24 @@ class SomeClass(ComplexModel):
c = SomeInnerClass.customize(not_wrapped=True)
class SomeService(Service):
- @srpc(SomeClass.customize(not_wrapped=True),
- _returns=SomeClass.customize(not_wrapped=True))
+ @srpc(
+ SomeClass.customize(not_wrapped=True),
+ _returns=SomeClass.customize(not_wrapped=True),
+ )
def some_call(p):
assert p.a == 1
- assert p.b == 's'
+ assert p.b == "s"
assert p.c.d == date(2018, 11, 22)
return p
- inner = {"a": 1, "b": "s", "c": {"d": '2018-11-22'}}
+ inner = {"a": 1, "b": "s", "c": {"d": "2018-11-22"}}
doc = {"some_call": [inner]}
- ctx = _dry_me([SomeService], doc, validator='soft')
+ ctx = _dry_me([SomeService], doc, validator="soft")
print(ctx.out_document)
d = convert_dict({"some_callResponse": {"some_callResult": inner}})
- self.assertEquals(ctx.out_document[0], d)
+ self.assertEqual(ctx.out_document[0], d)
def test_validation_freq_parent(self):
class C(ComplexModel):
@@ -1248,8 +1321,11 @@ def some_call(p):
try:
# must raise validation error for missing i
- _dry_me([SomeService], {"some_call": {'p': {'C': {'s': 'a'}}}},
- validator='soft')
+ _dry_me(
+ [SomeService],
+ {"some_call": {"p": {"C": {"s": "a"}}}},
+ validator="soft",
+ )
except ValidationError as e:
logger.exception(e)
pass
@@ -1260,7 +1336,7 @@ def some_call(p):
raise Exception("must raise ValidationError")
# must not raise anything for missing p because C has min_occurs=0
- _dry_me([SomeService], {"some_call": {}}, validator='soft')
+ _dry_me([SomeService], {"some_call": {}}, validator="soft")
def test_inheritance(self):
class P(ComplexModel):
@@ -1276,20 +1352,26 @@ class SomeService(Service):
def some_call(ctx):
result = C()
result.identifier = uuid.UUID(int=0)
- result.signature = 'yyyyyyyyyyy'
- result.foo = 'zzzzzz'
+ result.signature = "yyyyyyyyyyy"
+ result.foo = "zzzzzz"
result.bar = uuid.UUID(int=1)
return result
ctx = _dry_me([SomeService], {"some_call": []})
- s = self.loads(b''.join(ctx.out_string))
- d = {"some_callResponse": {"some_callResult": {"C": {
- 'identifier': '00000000-0000-0000-0000-000000000000',
- 'bar': '00000000-0000-0000-0000-000000000001',
- 'foo': 'zzzzzz',
- 'signature': 'yyyyyyyyyyy'
- }}}}
+ s = self.loads(b"".join(ctx.out_string))
+ d = {
+ "some_callResponse": {
+ "some_callResult": {
+ "C": {
+ "identifier": "00000000-0000-0000-0000-000000000000",
+ "bar": "00000000-0000-0000-0000-000000000001",
+ "foo": "zzzzzz",
+ "signature": "yyyyyyyyyyy",
+ }
+ }
+ }
+ }
assert s == d
@@ -1305,11 +1387,14 @@ def some_call(sc):
assert sc.s2 == "s2"
return C(s1="s1", s2="s2")
- doc = [{"C": {"s1": "s1","s2": "s2"}}]
+ doc = [{"C": {"s1": "s1", "s2": "s2"}}]
ctx = _dry_me([SomeService], {"some_call": doc})
- self.assertEquals(ctx.out_document[0], convert_dict(
- {'some_callResponse': {'some_callResult': {'C': {'s2': 's2'}}}})
+ self.assertEqual(
+ ctx.out_document[0],
+ convert_dict(
+ {"some_callResponse": {"some_callResult": {"C": {"s2": "s2"}}}}
+ ),
)
def test_polymorphic_deserialization(self):
@@ -1327,23 +1412,27 @@ class SomeService(Service):
def typeof(ctx, p):
return type(p).__name__
- ctx = _dry_me([SomeService],
- {"typeof": [{'C':{'sig':'a', 'foo': 'f'}}]},
- polymorphic=True)
+ ctx = _dry_me(
+ [SomeService],
+ {"typeof": [{"C": {"sig": "a", "foo": "f"}}]},
+ polymorphic=True,
+ )
- s = self.loads(b''.join(ctx.out_string))
- d = {"typeofResponse": {"typeofResult": 'C'}}
+ s = self.loads(b"".join(ctx.out_string))
+ d = {"typeofResponse": {"typeofResult": "C"}}
print(s)
print(d)
assert s == d
- ctx = _dry_me([SomeService],
- {"typeof": [{'D':{'sig':'b', 'bar': 5}}]},
- polymorphic=True)
+ ctx = _dry_me(
+ [SomeService],
+ {"typeof": [{"D": {"sig": "b", "bar": 5}}]},
+ polymorphic=True,
+ )
- s = self.loads(b''.join(ctx.out_string))
- d = {"typeofResponse": {"typeofResult": 'D'}}
+ s = self.loads(b"".join(ctx.out_string))
+ d = {"typeofResponse": {"typeofResult": "D"}}
print(s)
print(d)
@@ -1352,8 +1441,8 @@ def typeof(ctx, p):
def test_default(self):
class SomeComplexModel(ComplexModel):
_type_info = [
- ('a', Unicode),
- ('b', Unicode(default='default')),
+ ("a", Unicode),
+ ("b", Unicode(default="default")),
]
class SomeService(Service):
@@ -1361,24 +1450,27 @@ class SomeService(Service):
def some_method(s):
pass
- ctx = _dry_me([SomeService],
- {"some_method": [{"s": {"a": "x", "b": None}}]},
- polymorphic=True)
+ ctx = _dry_me(
+ [SomeService],
+ {"some_method": [{"s": {"a": "x", "b": None}}]},
+ polymorphic=True,
+ )
assert ctx.in_object.s.b == None
assert ctx.in_error is None
- ctx = _dry_me([SomeService], {"some_method": {"s": {"a": "x"}}},
- polymorphic=True)
+ ctx = _dry_me(
+ [SomeService], {"some_method": {"s": {"a": "x"}}}, polymorphic=True
+ )
- assert ctx.in_object.s.b == 'default'
+ assert ctx.in_object.s.b == "default"
assert ctx.in_error is None
def test_nillable_default(self):
class SomeComplexModel(ComplexModel):
_type_info = [
- ('a', Unicode),
- ('b', Unicode(min_occurs=1, default='default', nillable=True)),
+ ("a", Unicode),
+ ("b", Unicode(min_occurs=1, default="default", nillable=True)),
]
class SomeService(Service):
@@ -1386,17 +1478,21 @@ class SomeService(Service):
def some_method(s):
pass
- ctx = _dry_me([SomeService],
- {"some_method": [{"s": {"a": "x", "b": None}}]},
- polymorphic=True, validator='soft')
+ ctx = _dry_me(
+ [SomeService],
+ {"some_method": [{"s": {"a": "x", "b": None}}]},
+ polymorphic=True,
+ validator="soft",
+ )
assert ctx.in_object.s.b == None
assert ctx.in_error is None
- ctx = _dry_me([SomeService], {"some_method": {"s": {"a": "x"}}},
- polymorphic=True)
+ ctx = _dry_me(
+ [SomeService], {"some_method": {"s": {"a": "x"}}}, polymorphic=True
+ )
- assert ctx.in_object.s.b == 'default'
+ assert ctx.in_object.s.b == "default"
assert ctx.in_error is None
return Test
diff --git a/spyne/test/protocol/test_cloth.py b/spyne/test/protocol/test_cloth.py
index 965d852d2..c01e2a93b 100755
--- a/spyne/test/protocol/test_cloth.py
+++ b/spyne/test/protocol/test_cloth.py
@@ -20,18 +20,26 @@
from __future__ import print_function
import logging
+
logger = logging.getLogger(__name__)
import unittest
+from io import BytesIO
from lxml import etree, html
from lxml.builder import E
-from spyne import ComplexModel, XmlAttribute, Unicode, Array, Integer, \
- SelfReference, XmlData
+from spyne import (
+ Array,
+ ComplexModel,
+ Integer,
+ SelfReference,
+ Unicode,
+ XmlAttribute,
+ XmlData,
+)
from spyne.protocol.cloth import XmlCloth
from spyne.test import FakeContext
-from spyne.util.six import BytesIO
class TestModelCloth(unittest.TestCase):
@@ -79,8 +87,7 @@ def _run(self, inst, cls=None):
cls = inst.__class__
with etree.xmlfile(self.stream) as parent:
- XmlCloth().subserialize(self.ctx, cls, inst, parent,
- name=cls.__name__)
+ XmlCloth().subserialize(self.ctx, cls, inst, parent, name=cls.__name__)
elt = etree.fromstring(self.stream.getvalue())
@@ -88,7 +95,7 @@ def _run(self, inst, cls=None):
return elt
def test_simple(self):
- v = 'punk.'
+ v = "punk."
elt = self._run(v, Unicode)
assert elt.text == v
@@ -97,7 +104,7 @@ def test_complex_primitive(self):
class SomeObject(ComplexModel):
s = Unicode
- v = 'punk.'
+ v = "punk."
elt = self._run(SomeObject(s=v))
assert elt[0].text == v
@@ -110,7 +117,7 @@ class B(A):
s = Unicode
i = 42
- s = 'punk.'
+ s = "punk."
elt = self._run(B(i=i, s=s))
# order is important
@@ -142,8 +149,9 @@ def _run(self, inst, spid=None, cloth=None):
assert spid is None
with etree.xmlfile(self.stream) as parent:
- XmlCloth(cloth=cloth).set_identifier_prefix('spyne_') \
- .subserialize(self.ctx, cls, inst, parent)
+ XmlCloth(cloth=cloth).set_identifier_prefix("spyne_").subserialize(
+ self.ctx, cls, inst, parent
+ )
elt = etree.fromstring(self.stream.getvalue())
@@ -154,8 +162,8 @@ def test_simple_value(self):
class SomeObject(ComplexModel):
s = Unicode
- v = 'punk.'
- elt = self._run(SomeObject(s=v), spid='s')
+ v = "punk."
+ elt = self._run(SomeObject(s=v), spid="s")
assert elt[0].text == v
@@ -163,7 +171,7 @@ def test_simple_empty(self):
class SomeObject(ComplexModel):
s = Unicode
- elt = self._run(SomeObject(), spid='s')
+ elt = self._run(SomeObject(), spid="s")
assert len(elt) == 0
@@ -172,7 +180,7 @@ def _test_simple_empty_nonoptional(self):
class SomeObject(ComplexModel):
s = Unicode(min_occurs=1)
- elt = self._run(SomeObject(), spid='s')
+ elt = self._run(SomeObject(), spid="s")
assert elt[0].text is None
@@ -193,9 +201,9 @@ class SomeObject(ComplexModel):
cloth = etree.fromstring('')
- elt = self._run(SomeObject(d='data'), cloth=cloth)
+ elt = self._run(SomeObject(d="data"), cloth=cloth)
- assert elt.text == 'data'
+ assert elt.text == "data"
def test_xml_data_attr(self):
class SomeObject(ComplexModel):
@@ -203,9 +211,9 @@ class SomeObject(ComplexModel):
cloth = etree.fromstring('')
- elt = self._run(SomeObject(d='data'), cloth=cloth)
+ elt = self._run(SomeObject(d="data"), cloth=cloth)
- assert elt.text == 'data'
+ assert elt.text == "data"
def test_xml_data_attr_undesignated(self):
class SomeObject(ComplexModel):
@@ -213,12 +221,12 @@ class SomeObject(ComplexModel):
cloth = etree.fromstring('')
- elt = self._run(SomeObject(d='data'), cloth=cloth)
+ elt = self._run(SomeObject(d="data"), cloth=cloth)
- assert elt.text == 'data'
+ assert elt.text == "data"
def test_simple_value_xmlattribute(self):
- v = 'punk.'
+ v = "punk."
class SomeObject(ComplexModel):
s = XmlAttribute(Unicode(min_occurs=1))
@@ -226,42 +234,42 @@ class SomeObject(ComplexModel):
cloth = etree.fromstring("""""")
elt = self._run(SomeObject(s=v), cloth=cloth)
- assert elt.attrib['s'] == v
+ assert elt.attrib["s"] == v
def test_simple_value_xmlattribute_subname(self):
- v = 'punk.'
+ v = "punk."
class SomeObject(ComplexModel):
- s = XmlAttribute(Unicode(min_occurs=1, sub_name='foo'))
+ s = XmlAttribute(Unicode(min_occurs=1, sub_name="foo"))
cloth = etree.fromstring("""""")
elt = self._run(SomeObject(s=v), cloth=cloth)
- assert elt.attrib['foo'] == v
+ assert elt.attrib["foo"] == v
def test_simple_value_xmlattribute_non_immediate(self):
- v = 'punk.'
+ v = "punk."
class SomeObject(ComplexModel):
- s = XmlAttribute(Unicode(min_occurs=1, sub_name='foo'))
+ s = XmlAttribute(Unicode(min_occurs=1, sub_name="foo"))
cloth = etree.fromstring("""""")
elt = self._run(SomeObject(s=v), cloth=cloth)
- assert elt.attrib['foo'] == v
- assert elt[0].attrib['foo'] == v
+ assert elt.attrib["foo"] == v
+ assert elt[0].attrib["foo"] == v
def test_simple_value_xmlattribute_non_immediate_non_designated(self):
- v = 'punk.'
+ v = "punk."
class SomeObject(ComplexModel):
- s = Unicode(min_occurs=1, sub_name='foo')
+ s = Unicode(min_occurs=1, sub_name="foo")
cloth = etree.fromstring("""""")
elt = self._run(SomeObject(s=v), cloth=cloth)
- assert not 'foo' in elt.attrib
- assert elt[0].attrib['foo'] == v
+ assert not "foo" in elt.attrib
+ assert elt[0].attrib["foo"] == v
def test_non_tagbag(self):
cloth = E.a(
@@ -274,7 +282,7 @@ def test_non_tagbag(self):
),
spyne_id="i",
),
- spyne_tagbag='',
+ spyne_tagbag="",
)
class C2(ComplexModel):
@@ -285,9 +293,9 @@ class C1(ComplexModel):
c = C2
elt = self._run(C1(i=1, c=C2(i=2)), cloth=cloth)
- assert elt.xpath('//b/text()') == ['1']
+ assert elt.xpath("//b/text()") == ["1"]
# no order guarantee is given
- assert set(elt.xpath('//d/text()')) == set(['1', '2'])
+ assert set(elt.xpath("//d/text()")) == set(["1", "2"])
def test_array(self):
v = range(3)
@@ -304,7 +312,7 @@ class SomeObject(ComplexModel):
elt = self._run(SomeObject(s=v), cloth=cloth)
- assert elt.xpath('//c/text()') == [str(i) for i in v]
+ assert elt.xpath("//c/text()") == [str(i) for i in v]
def test_array_empty(self):
class SomeObject(ComplexModel):
@@ -315,7 +323,7 @@ class SomeObject(ComplexModel):
elt = self._run(SomeObject(), cloth=cloth)
- assert elt.xpath('//c') == []
+ assert elt.xpath("//c") == []
# FIXME: just fix it
def _test_array_empty_nonoptional(self):
@@ -327,14 +335,14 @@ class SomeObject(ComplexModel):
elt = self._run(SomeObject(), cloth=cloth)
- assert elt.xpath('//c') == [cloth[0][0]]
+ assert elt.xpath("//c") == [cloth[0][0]]
def test_simple_two_tags(self):
class SomeObject(ComplexModel):
s = Unicode
i = Integer
- v = SomeObject(s='s', i=5)
+ v = SomeObject(s="s", i=5)
cloth = E.a(
E.b1(),
@@ -352,22 +360,22 @@ class SomeObject(ComplexModel):
elt = self._run(v, cloth=cloth)
print(etree.tostring(elt, pretty_print=True))
- assert elt[0].tag == 'b1'
- assert elt[1].tag == 'b2'
- assert elt[1][0].tag == 'c1'
- assert elt[1][0].text == 's'
- assert elt[1][1].tag == 'c2'
- assert elt[2].tag == 'e'
- assert elt[2][0].tag == 'g1'
- assert elt[2][1].tag == 'g2'
- assert elt[2][1].text == '5'
- assert elt[2][2].tag == 'g3'
+ assert elt[0].tag == "b1"
+ assert elt[1].tag == "b2"
+ assert elt[1][0].tag == "c1"
+ assert elt[1][0].text == "s"
+ assert elt[1][1].tag == "c2"
+ assert elt[2].tag == "e"
+ assert elt[2][0].tag == "g1"
+ assert elt[2][1].tag == "g2"
+ assert elt[2][1].text == "5"
+ assert elt[2][2].tag == "g3"
def test_sibling_order(self):
class SomeObject(ComplexModel):
s = Unicode
- v = SomeObject(s='s')
+ v = SomeObject(s="s")
cloth = E.a(
E.b1(),
@@ -382,20 +390,20 @@ class SomeObject(ComplexModel):
elt = self._run(v, cloth=cloth)
print(etree.tostring(elt, pretty_print=True))
- assert elt[0].tag == 'b1'
- assert elt[1].tag == 'b2'
- assert elt[1][0].tag == 'c0'
- assert elt[1][1].tag == 'c1'
- assert elt[1][2].tag == 'c2'
- assert elt[1][2].text == 's'
- assert elt[1][3].tag == 'c3'
- assert elt[1][4].tag == 'c4'
+ assert elt[0].tag == "b1"
+ assert elt[1].tag == "b2"
+ assert elt[1][0].tag == "c0"
+ assert elt[1][1].tag == "c1"
+ assert elt[1][2].tag == "c2"
+ assert elt[1][2].text == "s"
+ assert elt[1][3].tag == "c3"
+ assert elt[1][4].tag == "c4"
def test_parent_text(self):
class SomeObject(ComplexModel):
s = Unicode
- v = SomeObject(s='s')
+ v = SomeObject(s="s")
cloth = E.a(
"text 0",
@@ -406,17 +414,17 @@ class SomeObject(ComplexModel):
elt = self._run(v, cloth=cloth)
print(etree.tostring(elt, pretty_print=True))
- assert elt.tag == 'a'
- assert elt.text == 'text 0'
+ assert elt.tag == "a"
+ assert elt.text == "text 0"
- assert elt[0].tag == 'b1'
- assert elt[0].text == 's'
+ assert elt[0].tag == "b1"
+ assert elt[0].text == "s"
def test_anc_text(self):
class SomeObject(ComplexModel):
s = Unicode
- v = SomeObject(s='s')
+ v = SomeObject(s="s")
cloth = E.a(
E.b1(
@@ -429,16 +437,16 @@ class SomeObject(ComplexModel):
elt = self._run(v, cloth=cloth)
print(etree.tostring(elt, pretty_print=True))
- assert elt[0].tag == 'b1'
- assert elt[0].text == 'text 1'
- assert elt[0][0].tag == 'c1'
- assert elt[0][0].text == 's'
+ assert elt[0].tag == "b1"
+ assert elt[0].text == "text 1"
+ assert elt[0][0].tag == "c1"
+ assert elt[0][0].text == "s"
def test_prevsibl_tail(self):
class SomeObject(ComplexModel):
s = Unicode
- v = SomeObject(s='s')
+ v = SomeObject(s="s")
cloth = E.a(
E.b1(
@@ -452,16 +460,16 @@ class SomeObject(ComplexModel):
elt = self._run(v, cloth=cloth)
print(etree.tostring(elt, pretty_print=True))
- assert elt[0].tag == 'b1'
- assert elt[0][0].tag == 'c1'
- assert elt[0][0].tail == 'text 2'
- assert elt[0][1].text == 's'
+ assert elt[0].tag == "b1"
+ assert elt[0][0].tag == "c1"
+ assert elt[0][0].tail == "text 2"
+ assert elt[0][1].text == "s"
def test_sibling_tail_close(self):
class SomeObject(ComplexModel):
s = Unicode
- v = SomeObject(s='s')
+ v = SomeObject(s="s")
cloth = E.a(
E.b0(spyne_id="s"),
@@ -472,16 +480,16 @@ class SomeObject(ComplexModel):
elt = self._run(v, cloth=cloth)
print(etree.tostring(elt, pretty_print=True))
- assert elt[0].tag == 'b0'
- assert elt[0].text == 's'
- assert elt[0].tail == 'text 3'
+ assert elt[0].tag == "b0"
+ assert elt[0].text == "s"
+ assert elt[0].tail == "text 3"
def test_sibling_tail_close_sibling(self):
class SomeObject(ComplexModel):
s = Unicode
i = Integer
- v = SomeObject(s='s', i=5)
+ v = SomeObject(s="s", i=5)
cloth = E.a(
E.b0(spyne_id="s"),
@@ -493,16 +501,16 @@ class SomeObject(ComplexModel):
elt = self._run(v, cloth=cloth)
print(etree.tostring(elt, pretty_print=True))
- assert elt[0].tag == 'b0'
- assert elt[0].text == 's'
- assert elt[0].tail == 'text 3'
+ assert elt[0].tag == "b0"
+ assert elt[0].text == "s"
+ assert elt[0].tail == "text 3"
def test_sibling_tail_close_anc(self):
class SomeObject(ComplexModel):
s = Unicode
i = Integer
- v = SomeObject(s='s', i=5)
+ v = SomeObject(s="s", i=5)
cloth = E.a(
E.b0(),
@@ -517,16 +525,16 @@ class SomeObject(ComplexModel):
E.b2(
E.c1(spyne_id="i"),
"text 4",
- )
+ ),
)
print(etree.tostring(cloth, pretty_print=True))
elt = self._run(v, cloth=cloth)
print(etree.tostring(elt, pretty_print=True))
- assert elt.xpath('/a/b1/c0')[0].tail == 'text 1'
- assert elt.xpath('/a/b1/c1')[0].tail == 'text 2'
- assert elt.xpath('/a/b2/c1')[0].tail == 'text 4'
+ assert elt.xpath("/a/b1/c0")[0].tail == "text 1"
+ assert elt.xpath("/a/b1/c1")[0].tail == "text 2"
+ assert elt.xpath("/a/b2/c1")[0].tail == "text 4"
def test_nested_conflicts(self):
class SomeObject(ComplexModel):
@@ -534,7 +542,7 @@ class SomeObject(ComplexModel):
i = Integer
c = SelfReference
- v = SomeObject(s='x', i=1, c=SomeObject(s='y', i=2))
+ v = SomeObject(s="x", i=1, c=SomeObject(s="y", i=2))
cloth = E.a(
E.b0(),
@@ -553,18 +561,18 @@ class SomeObject(ComplexModel):
E.b2(
E.c2(spyne_id="i"),
"text 4",
- )
+ ),
)
print(etree.tostring(cloth, pretty_print=True))
elt = self._run(v, cloth=cloth)
print(etree.tostring(elt, pretty_print=True))
- assert elt.xpath('/a/b1/c0')[0].text == str(v.s)
- assert elt.xpath('/a/b1/c1/d0')[0].text == str(v.c.s)
- assert elt.xpath('/a/b1/c1/d1')[0].text == str(v.c.i)
- assert elt.xpath('/a/b2/c2')[0].text == str(v.i)
+ assert elt.xpath("/a/b1/c0")[0].text == str(v.s)
+ assert elt.xpath("/a/b1/c1/d0")[0].text == str(v.c.s)
+ assert elt.xpath("/a/b1/c1/d1")[0].text == str(v.c.i)
+ assert elt.xpath("/a/b2/c2")[0].text == str(v.i)
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/protocol/test_html_microformat.py b/spyne/test/protocol/test_html_microformat.py
index 8a0df4916..8a26a8516 100755
--- a/spyne/test/protocol/test_html_microformat.py
+++ b/spyne/test/protocol/test_html_microformat.py
@@ -18,6 +18,7 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
import unittest
@@ -26,16 +27,13 @@
from spyne.application import Application
from spyne.decorator import srpc
-from spyne.model.primitive import Integer
-from spyne.model.primitive import String
-from spyne.model.complex import Array
-from spyne.model.complex import ComplexModel
-from spyne.protocol.http import HttpRpc
+from spyne.model.complex import Array, ComplexModel
+from spyne.model.primitive import Integer, String
from spyne.protocol.html import HtmlMicroFormat
+from spyne.protocol.http import HttpRpc
+from spyne.server.wsgi import WsgiApplication, WsgiMethodContext
from spyne.service import Service
-from spyne.server.wsgi import WsgiMethodContext
-from spyne.server.wsgi import WsgiApplication
-from spyne.util.test import show, call_wsgi_app_kwargs
+from spyne.util.test import call_wsgi_app_kwargs, show
class TestHtmlMicroFormat(unittest.TestCase):
@@ -45,56 +43,73 @@ class SomeService(Service):
def some_call(s):
return s
- app = Application([SomeService], 'tns',
- in_protocol=HttpRpc(hier_delim='_'),
- out_protocol=HtmlMicroFormat(doctype=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(hier_delim="_"),
+ out_protocol=HtmlMicroFormat(doctype=None),
+ )
server = WsgiApplication(app)
- initial_ctx = WsgiMethodContext(server, {
- 'QUERY_STRING': 's=s',
- 'PATH_INFO': '/some_call',
- 'REQUEST_METHOD': 'GET',
- 'SERVER_NAME': 'localhost',
- }, 'some-content-type')
-
- ctx, = server.generate_contexts(initial_ctx)
+ initial_ctx = WsgiMethodContext(
+ server,
+ {
+ "QUERY_STRING": "s=s",
+ "PATH_INFO": "/some_call",
+ "REQUEST_METHOD": "GET",
+ "SERVER_NAME": "localhost",
+ },
+ "some-content-type",
+ )
+
+ (ctx,) = server.generate_contexts(initial_ctx)
assert ctx.in_error is None
server.get_in_object(ctx)
server.get_out_object(ctx)
server.get_out_string(ctx)
- assert b''.join(ctx.out_string) == b''
+ assert (
+ b"".join(ctx.out_string) == b''
+ )
def test_multiple_return(self):
class SomeService(Service):
@srpc(_returns=[Integer, String])
def some_call():
- return 1, 's'
-
- app = Application([SomeService], 'tns',
- in_protocol=HttpRpc(hier_delim='_'),
- out_protocol=HtmlMicroFormat(doctype=None))
+ return 1, "s"
+
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(hier_delim="_"),
+ out_protocol=HtmlMicroFormat(doctype=None),
+ )
server = WsgiApplication(app)
- initial_ctx = WsgiMethodContext(server, {
- 'QUERY_STRING': '',
- 'PATH_INFO': '/some_call',
- 'REQUEST_METHOD': 'GET',
- 'SERVER_NAME': 'localhost',
- }, 'some-content-type')
-
- ctx, = server.generate_contexts(initial_ctx)
+ initial_ctx = WsgiMethodContext(
+ server,
+ {
+ "QUERY_STRING": "",
+ "PATH_INFO": "/some_call",
+ "REQUEST_METHOD": "GET",
+ "SERVER_NAME": "localhost",
+ },
+ "some-content-type",
+ )
+
+ (ctx,) = server.generate_contexts(initial_ctx)
server.get_in_object(ctx)
server.get_out_object(ctx)
server.get_out_string(ctx)
- assert b''.join(ctx.out_string) == b''
-
+ assert (
+ b"".join(ctx.out_string) == b''
+ )
def test_complex(self):
class CM(ComplexModel):
@@ -109,21 +124,28 @@ class CCM(ComplexModel):
class SomeService(Service):
@srpc(CCM, _returns=CCM)
def some_call(ccm):
- return CCM(c=ccm.c,i=ccm.i, s=ccm.s)
-
- app = Application([SomeService], 'tns',
- in_protocol=HttpRpc(hier_delim='_'),
- out_protocol=HtmlMicroFormat(doctype=None))
+ return CCM(c=ccm.c, i=ccm.i, s=ccm.s)
+
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(hier_delim="_"),
+ out_protocol=HtmlMicroFormat(doctype=None),
+ )
server = WsgiApplication(app)
- initial_ctx = WsgiMethodContext(server, {
- 'QUERY_STRING': 'ccm_c_s=abc&ccm_c_i=123&ccm_i=456&ccm_s=def',
- 'PATH_INFO': '/some_call',
- 'REQUEST_METHOD': 'GET',
- 'SERVER_NAME': 'localhost',
- }, 'some-content-type')
-
- ctx, = server.generate_contexts(initial_ctx)
+ initial_ctx = WsgiMethodContext(
+ server,
+ {
+ "QUERY_STRING": "ccm_c_s=abc&ccm_c_i=123&ccm_i=456&ccm_s=def",
+ "PATH_INFO": "/some_call",
+ "REQUEST_METHOD": "GET",
+ "SERVER_NAME": "localhost",
+ },
+ "some-content-type",
+ )
+
+ (ctx,) = server.generate_contexts(initial_ctx)
server.get_in_object(ctx)
server.get_out_object(ctx)
server.get_out_string(ctx)
@@ -143,67 +165,78 @@ def some_call(ccm):
#
#
- elt = html.fromstring(b''.join(ctx.out_string))
+ elt = html.fromstring(b"".join(ctx.out_string))
print(html.tostring(elt, pretty_print=True))
- resp = elt.find_class('some_callResponse')
+ resp = elt.find_class("some_callResponse")
assert len(resp) == 1
- res = resp[0].find_class('some_callResult')
+ res = resp[0].find_class("some_callResult")
assert len(res) == 1
i = res[0].findall('div[@class="i"]')
assert len(i) == 1
- assert i[0].text == '456'
+ assert i[0].text == "456"
c = res[0].findall('div[@class="c"]')
assert len(c) == 1
c_i = c[0].findall('div[@class="i"]')
assert len(c_i) == 1
- assert c_i[0].text == '123'
+ assert c_i[0].text == "123"
c_s = c[0].findall('div[@class="s"]')
assert len(c_s) == 1
- assert c_s[0].text == 'abc'
+ assert c_s[0].text == "abc"
s = res[0].findall('div[@class="s"]')
assert len(s) == 1
- assert s[0].text == 'def'
+ assert s[0].text == "def"
def test_multiple(self):
class SomeService(Service):
- @srpc(String(max_occurs='unbounded'), _returns=String)
+ @srpc(String(max_occurs="unbounded"), _returns=String)
def some_call(s):
print(s)
- return '\n'.join(s)
-
- app = Application([SomeService], 'tns',
- in_protocol=HttpRpc(hier_delim='_'),
- out_protocol=HtmlMicroFormat(doctype=None))
+ return "\n".join(s)
+
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(hier_delim="_"),
+ out_protocol=HtmlMicroFormat(doctype=None),
+ )
server = WsgiApplication(app)
- initial_ctx = WsgiMethodContext(server, {
- 'QUERY_STRING': 's=1&s=2',
- 'PATH_INFO': '/some_call',
- 'REQUEST_METHOD': 'GET',
- 'SERVER_NAME': 'localhost',
- }, 'some-content-type')
-
- ctx, = server.generate_contexts(initial_ctx)
+ initial_ctx = WsgiMethodContext(
+ server,
+ {
+ "QUERY_STRING": "s=1&s=2",
+ "PATH_INFO": "/some_call",
+ "REQUEST_METHOD": "GET",
+ "SERVER_NAME": "localhost",
+ },
+ "some-content-type",
+ )
+
+ (ctx,) = server.generate_contexts(initial_ctx)
server.get_in_object(ctx)
server.get_out_object(ctx)
server.get_out_string(ctx)
- assert b''.join(ctx.out_string) == (b'')
+ assert b"".join(ctx.out_string) == (
+ b''
+ )
- ctx, = server.generate_contexts(initial_ctx)
+ (ctx,) = server.generate_contexts(initial_ctx)
server.get_in_object(ctx)
server.get_out_object(ctx)
server.get_out_string(ctx)
- assert b''.join(ctx.out_string) == b''
+ assert (
+ b"".join(ctx.out_string) == b''
+ )
def test_before_first_root(self):
class CM(ComplexModel):
@@ -218,21 +251,23 @@ class CCM(ComplexModel):
class SomeService(Service):
@srpc(CCM, _returns=Array(CCM))
def some_call(ccm):
- return [CCM(c=ccm.c,i=ccm.i, s=ccm.s)] * 2
+ return [CCM(c=ccm.c, i=ccm.i, s=ccm.s)] * 2
cb_called = [False]
+
def _cb(ctx, cls, inst, parent, name, **kwargs):
assert not cb_called[0]
cb_called[0] = True
- app = Application([SomeService], 'tns',
- in_protocol=HttpRpc(hier_delim='_'),
- out_protocol=HtmlMicroFormat(
- doctype=None, before_first_root=_cb))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(hier_delim="_"),
+ out_protocol=HtmlMicroFormat(doctype=None, before_first_root=_cb),
+ )
server = WsgiApplication(app)
- call_wsgi_app_kwargs(server,
- ccm_c_s='abc', ccm_c_i=123, ccm_i=456, ccm_s='def')
+ call_wsgi_app_kwargs(server, ccm_c_s="abc", ccm_c_i=123, ccm_i=456, ccm_s="def")
assert cb_called[0]
@@ -249,15 +284,19 @@ class CCM(ComplexModel):
class SomeService(Service):
@srpc(CCM, _returns=Array(CCM))
def some_call(ccm):
- return [CCM(c=ccm.c,i=ccm.i, s=ccm.s)] * 2
-
- app = Application([SomeService], 'tns',
- in_protocol=HttpRpc(hier_delim='_'),
- out_protocol=HtmlMicroFormat(doctype=None))
+ return [CCM(c=ccm.c, i=ccm.i, s=ccm.s)] * 2
+
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(hier_delim="_"),
+ out_protocol=HtmlMicroFormat(doctype=None),
+ )
server = WsgiApplication(app)
- out_string = call_wsgi_app_kwargs(server,
- ccm_c_s='abc', ccm_c_i=123, ccm_i=456, ccm_s='def')
+ out_string = call_wsgi_app_kwargs(
+ server, ccm_c_s="abc", ccm_c_i=123, ccm_i=456, ccm_s="def"
+ )
#
# Here's what this is supposed to return:
@@ -286,9 +325,9 @@ def some_call(ccm):
elt = html.fromstring(out_string)
show(elt, "TestHtmlMicroFormat.test_complex_array")
- resp = elt.find_class('some_callResponse')
+ resp = elt.find_class("some_callResponse")
assert len(resp) == 1
- res = resp[0].find_class('some_callResult')
+ res = resp[0].find_class("some_callResult")
assert len(res) == 1
assert len(res[0].find_class("CCM")) == 2
@@ -296,5 +335,6 @@ def some_call(ccm):
# We don't need to test the rest as the test_complex test takes care of
# that
-if __name__ == '__main__':
+
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/protocol/test_html_table.py b/spyne/test/protocol/test_html_table.py
index d979356e3..9f15bd425 100755
--- a/spyne/test/protocol/test_html_table.py
+++ b/spyne/test/protocol/test_html_table.py
@@ -18,6 +18,7 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
import unittest
@@ -26,30 +27,27 @@
from spyne.application import Application
from spyne.decorator import srpc
-from spyne.model.primitive import Integer, Unicode
-from spyne.model.primitive import String
-from spyne.model.primitive import AnyUri
-from spyne.model.complex import Array
-from spyne.model.complex import ComplexModel
-from spyne.protocol.http import HttpRpc
+from spyne.model.complex import Array, ComplexModel
+from spyne.model.primitive import AnyUri, Integer, String, Unicode
from spyne.protocol.html.table import HtmlColumnTable, HtmlRowTable
-from spyne.service import Service
+from spyne.protocol.http import HttpRpc
from spyne.server.wsgi import WsgiApplication
-from spyne.util.test import show, call_wsgi_app_kwargs, call_wsgi_app
+from spyne.service import Service
+from spyne.util.test import call_wsgi_app, call_wsgi_app_kwargs, show
class CM(ComplexModel):
_type_info = [
- ('i', Integer),
- ('s', String),
+ ("i", Integer),
+ ("s", String),
]
class CCM(ComplexModel):
_type_info = [
- ('c', CM),
- ('i', Integer),
- ('s', String),
+ ("c", CM),
+ ("i", Integer),
+ ("s", String),
]
@@ -60,72 +58,83 @@ class SomeService(Service):
def some_call(ccm):
return [ccm] * 5
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(),
- out_protocol=HtmlColumnTable(field_type_name_attr=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HtmlColumnTable(field_type_name_attr=None),
+ )
server = WsgiApplication(app)
- out_string = call_wsgi_app_kwargs(server,
- ccm_i='456',
- ccm_s='def',
- ccm_c_i='123',
- ccm_c_s='abc',
- )
+ out_string = call_wsgi_app_kwargs(
+ server,
+ ccm_i="456",
+ ccm_s="def",
+ ccm_c_i="123",
+ ccm_c_s="abc",
+ )
elt = etree.fromstring(out_string)
- show(elt, 'TestHtmlColumnTable.test_complex_array')
+ show(elt, "TestHtmlColumnTable.test_complex_array")
elt = html.fromstring(out_string)
- row, = elt[0] # thead
+ (row,) = elt[0] # thead
cell = row.findall('th[@class="i"]')
assert len(cell) == 1
- assert cell[0].text == 'i'
+ assert cell[0].text == "i"
cell = row.findall('th[@class="s"]')
assert len(cell) == 1
- assert cell[0].text == 's'
+ assert cell[0].text == "s"
- for row in elt[1]: # tbody
+ for row in elt[1]: # tbody
cell = row.xpath('td[@class="i"]')
assert len(cell) == 1
- assert cell[0].text == '456'
+ assert cell[0].text == "456"
cell = row.xpath('td[@class="c"]//td[@class="i"]')
assert len(cell) == 1
- assert cell[0].text == '123'
+ assert cell[0].text == "123"
cell = row.xpath('td[@class="c"]//td[@class="s"]')
assert len(cell) == 1
- assert cell[0].text == 'abc'
+ assert cell[0].text == "abc"
cell = row.xpath('td[@class="s"]')
assert len(cell) == 1
- assert cell[0].text == 'def'
+ assert cell[0].text == "def"
def test_string_array(self):
class SomeService(Service):
- @srpc(String(max_occurs='unbounded'), _returns=Array(String))
+ @srpc(String(max_occurs="unbounded"), _returns=Array(String))
def some_call(s):
return s
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(),
- out_protocol=HtmlColumnTable(
- field_name_attr=None, field_type_name_attr=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HtmlColumnTable(
+ field_name_attr=None, field_type_name_attr=None
+ ),
+ )
server = WsgiApplication(app)
- out_string = call_wsgi_app(server, body_pairs=(('s', '1'), ('s', '2')))
+ out_string = call_wsgi_app(server, body_pairs=(("s", "1"), ("s", "2")))
elt = etree.fromstring(out_string)
show(elt, "TestHtmlColumnTable.test_string_array")
- assert out_string.decode('utf8') == \
- '' \
- '' \
- '| some_callResponse |
' \
- '' \
- '' \
- '| 1 |
' \
- '| 2 |
' \
- '' \
- '
'
+ assert (
+ out_string.decode("utf8") == ''
+ ""
+ "| some_callResponse |
"
+ ""
+ ""
+ "| 1 |
"
+ "| 2 |
"
+ ""
+ "
"
+ )
def test_anyuri_string(self):
_link = "http://arskom.com.tr/"
@@ -138,16 +147,20 @@ class SomeService(Service):
def some_call():
return [C(c=_link)]
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(),
- out_protocol=HtmlColumnTable(field_type_name_attr=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HtmlColumnTable(field_type_name_attr=None),
+ )
server = WsgiApplication(app)
out_string = call_wsgi_app_kwargs(server)
elt = html.fromstring(out_string)
show(elt, "TestHtmlColumnTable.test_anyuri_string")
- assert elt.xpath('//td[@class="c"]')[0][0].tag == 'a'
- assert elt.xpath('//td[@class="c"]')[0][0].attrib['href'] == _link
+ assert elt.xpath('//td[@class="c"]')[0][0].tag == "a"
+ assert elt.xpath('//td[@class="c"]')[0][0].attrib["href"] == _link
def test_anyuri_uri_value(self):
_link = "http://arskom.com.tr/"
@@ -161,52 +174,55 @@ class SomeService(Service):
def some_call():
return [C(c=AnyUri.Value(_link, text=_text))]
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(),
- out_protocol=HtmlColumnTable(field_type_name_attr=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HtmlColumnTable(field_type_name_attr=None),
+ )
server = WsgiApplication(app)
out_string = call_wsgi_app_kwargs(server)
elt = html.fromstring(out_string)
print(html.tostring(elt, pretty_print=True))
- assert elt.xpath('//td[@class="c"]')[0][0].tag == 'a'
+ assert elt.xpath('//td[@class="c"]')[0][0].tag == "a"
assert elt.xpath('//td[@class="c"]')[0][0].text == _text
- assert elt.xpath('//td[@class="c"]')[0][0].attrib['href'] == _link
+ assert elt.xpath('//td[@class="c"]')[0][0].attrib["href"] == _link
def test_row_subprot(self):
+ from urllib.parse import urlencode
+
from lxml.html.builder import E
- from spyne.protocol.html import HtmlBase
- from spyne.util.six.moves.urllib.parse import urlencode
- from spyne.protocol.html import HtmlMicroFormat
+
+ from spyne.protocol.html import HtmlBase, HtmlMicroFormat
class SearchProtocol(HtmlBase):
def to_parent(self, ctx, cls, inst, parent, name, **kwargs):
- s = self.to_unicode(cls._type_info['query'], inst.query)
+ s = self.to_unicode(cls._type_info["query"], inst.query)
q = urlencode({"q": s})
- parent.write(E.a("Search %s" % inst.query,
- href="{}?{}".format(inst.uri, q)))
+ parent.write(
+ E.a("Search %s" % inst.query, href="{}?{}".format(inst.uri, q))
+ )
def column_table_gen_header(self, ctx, cls, parent, name):
- parent.write(E.thead(E.th("Search",
- **{'class': 'search-link'})))
+ parent.write(E.thead(E.th("Search", **{"class": "search-link"})))
- def column_table_before_row(self, ctx, cls, inst, parent, name,**_):
- ctxstack = getattr(ctx.protocol[self],
- 'array_subprot_ctxstack', [])
+ def column_table_before_row(self, ctx, cls, inst, parent, name, **_):
+ ctxstack = getattr(ctx.protocol[self], "array_subprot_ctxstack", [])
- tr_ctx = parent.element('tr')
+ tr_ctx = parent.element("tr")
tr_ctx.__enter__()
ctxstack.append(tr_ctx)
- td_ctx = parent.element('td', **{'class': "search-link"})
+ td_ctx = parent.element("td", **{"class": "search-link"})
td_ctx.__enter__()
ctxstack.append(td_ctx)
ctx.protocol[self].array_subprot_ctxstack = ctxstack
- def column_table_after_row(self, ctx, cls, inst, parent, name,
- **kwargs):
+ def column_table_after_row(self, ctx, cls, inst, parent, name, **kwargs):
ctxstack = ctx.protocol[self].array_subprot_ctxstack
for elt_ctx in reversed(ctxstack):
@@ -227,12 +243,13 @@ class SomeService(Service):
@srpc(_returns=SearchTable)
def some_call():
return [
- Search(query='Arskom', uri='https://www.google.com/search'),
- Search(query='Spyne', uri='https://www.bing.com/search'),
+ Search(query="Arskom", uri="https://www.google.com/search"),
+ Search(query="Spyne", uri="https://www.bing.com/search"),
]
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(),
- out_protocol=HtmlMicroFormat())
+ app = Application(
+ [SomeService], "tns", in_protocol=HttpRpc(), out_protocol=HtmlMicroFormat()
+ )
server = WsgiApplication(app)
out_string = call_wsgi_app_kwargs(server)
@@ -240,12 +257,14 @@ def some_call():
elt = html.fromstring(out_string)
print(html.tostring(elt, pretty_print=True))
- assert elt.xpath('//td[@class="search-link"]/a/text()') == \
- ['Search Arskom', 'Search Spyne']
+ assert elt.xpath('//td[@class="search-link"]/a/text()') == [
+ "Search Arskom",
+ "Search Spyne",
+ ]
assert elt.xpath('//td[@class="search-link"]/a/@href') == [
- 'https://www.google.com/search?q=Arskom',
- 'https://www.bing.com/search?q=Spyne',
+ "https://www.google.com/search?q=Arskom",
+ "https://www.bing.com/search?q=Spyne",
]
assert elt.xpath('//th[@class="search-link"]/text()') == ["Search"]
@@ -263,16 +282,20 @@ class SomeService(Service):
def some_call():
return C(c=_link)
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(),
- out_protocol=HtmlRowTable(field_type_name_attr=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HtmlRowTable(field_type_name_attr=None),
+ )
server = WsgiApplication(app)
out_string = call_wsgi_app_kwargs(server)
elt = html.fromstring(out_string)
print(html.tostring(elt, pretty_print=True))
- assert elt.xpath('//td[@class="c"]')[0][0].tag == 'a'
- assert elt.xpath('//td[@class="c"]')[0][0].attrib['href'] == _link
+ assert elt.xpath('//td[@class="c"]')[0][0].tag == "a"
+ assert elt.xpath('//td[@class="c"]')[0][0].attrib["href"] == _link
def test_anyuri_uri_value(self):
_link = "http://arskom.com.tr/"
@@ -286,17 +309,21 @@ class SomeService(Service):
def some_call():
return C(c=AnyUri.Value(_link, text=_text))
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(),
- out_protocol=HtmlRowTable(field_type_name_attr=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HtmlRowTable(field_type_name_attr=None),
+ )
server = WsgiApplication(app)
out_string = call_wsgi_app_kwargs(server)
elt = html.fromstring(out_string)
print(html.tostring(elt, pretty_print=True))
- assert elt.xpath('//td[@class="c"]')[0][0].tag == 'a'
+ assert elt.xpath('//td[@class="c"]')[0][0].tag == "a"
assert elt.xpath('//td[@class="c"]')[0][0].text == _text
- assert elt.xpath('//td[@class="c"]')[0][0].attrib['href'] == _link
+ assert elt.xpath('//td[@class="c"]')[0][0].attrib["href"] == _link
def test_complex(self):
class SomeService(Service):
@@ -304,14 +331,18 @@ class SomeService(Service):
def some_call(ccm):
return ccm
- app = Application([SomeService], 'tns',
- in_protocol=HttpRpc(hier_delim="_"),
- out_protocol=HtmlRowTable(field_type_name_attr=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(hier_delim="_"),
+ out_protocol=HtmlRowTable(field_type_name_attr=None),
+ )
server = WsgiApplication(app)
- out_string = call_wsgi_app_kwargs(server, 'some_call',
- ccm_c_s='abc', ccm_c_i='123', ccm_i='456', ccm_s='def')
+ out_string = call_wsgi_app_kwargs(
+ server, "some_call", ccm_c_s="abc", ccm_c_i="123", ccm_i="456", ccm_s="def"
+ )
elt = html.fromstring(out_string)
show(elt, "TestHtmlRowTable.test_complex")
@@ -350,159 +381,175 @@ def some_call(ccm):
"""
print(html.tostring(elt, pretty_print=True))
- resp = elt.find_class('CCM')
+ resp = elt.find_class("CCM")
assert len(resp) == 1
- assert elt.xpath('tbody/tr/th[@class="i"]/text()')[0] == 'i'
- assert elt.xpath('tbody/tr/td[@class="i"]/text()')[0] == '456'
+ assert elt.xpath('tbody/tr/th[@class="i"]/text()')[0] == "i"
+ assert elt.xpath('tbody/tr/td[@class="i"]/text()')[0] == "456"
- assert elt.xpath('tbody/tr/td[@class="c"]//th[@class="i"]/text()')[0] == 'i'
- assert elt.xpath('tbody/tr/td[@class="c"]//td[@class="i"]/text()')[0] == '123'
+ assert elt.xpath('tbody/tr/td[@class="c"]//th[@class="i"]/text()')[0] == "i"
+ assert elt.xpath('tbody/tr/td[@class="c"]//td[@class="i"]/text()')[0] == "123"
- assert elt.xpath('tbody/tr/td[@class="c"]//th[@class="s"]/text()')[0] == 's'
- assert elt.xpath('tbody/tr/td[@class="c"]//td[@class="s"]/text()')[0] == 'abc'
+ assert elt.xpath('tbody/tr/td[@class="c"]//th[@class="s"]/text()')[0] == "s"
+ assert elt.xpath('tbody/tr/td[@class="c"]//td[@class="s"]/text()')[0] == "abc"
- assert elt.xpath('tbody/tr/th[@class="s"]/text()')[0] == 's'
- assert elt.xpath('tbody/tr/td[@class="s"]/text()')[0] == 'def'
+ assert elt.xpath('tbody/tr/th[@class="s"]/text()')[0] == "s"
+ assert elt.xpath('tbody/tr/td[@class="s"]/text()')[0] == "def"
def test_string_array(self):
class SomeService(Service):
- @srpc(String(max_occurs='unbounded'), _returns=Array(String))
+ @srpc(String(max_occurs="unbounded"), _returns=Array(String))
def some_call(s):
return s
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(),
- out_protocol=HtmlRowTable(field_name_attr=None,
- field_type_name_attr=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HtmlRowTable(field_name_attr=None, field_type_name_attr=None),
+ )
server = WsgiApplication(app)
- out_string = call_wsgi_app(server, body_pairs=(('s', '1'), ('s', '2')) )
- show(html.fromstring(out_string), 'TestHtmlRowTable.test_string_array')
- assert out_string.decode('utf8') == \
- '' \
- '
' \
- '' \
- '| string | ' \
- '' \
- '' \
- '' \
- '| 1 | ' \
- ' ' \
- '' \
- '| 2 | ' \
- ' ' \
- ' ' \
- ' | ' \
- '
' \
- '
' \
- '
'
+ out_string = call_wsgi_app(server, body_pairs=(("s", "1"), ("s", "2")))
+ show(html.fromstring(out_string), "TestHtmlRowTable.test_string_array")
+ assert (
+ out_string.decode("utf8") == ""
+ '
'
+ ""
+ "| string | "
+ ""
+ ""
+ ""
+ "| 1 | "
+ " "
+ ""
+ "| 2 | "
+ " "
+ " "
+ " | "
+ "
"
+ "
"
+ "
"
+ )
def test_string_array_no_header(self):
class SomeService(Service):
- @srpc(String(max_occurs='unbounded'), _returns=Array(String))
+ @srpc(String(max_occurs="unbounded"), _returns=Array(String))
def some_call(s):
return s
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(),
- out_protocol=HtmlRowTable(header=False,
- field_name_attr=None, field_type_name_attr=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HtmlRowTable(
+ header=False, field_name_attr=None, field_type_name_attr=None
+ ),
+ )
server = WsgiApplication(app)
- out_string = call_wsgi_app(server, body_pairs=(('s', '1'), ('s', '2')) )
- #FIXME: Needs a proper test with xpaths and all.
- show(html.fromstring(out_string), 'TestHtmlRowTable.test_string_array_no_header')
- assert out_string.decode('utf8') == \
- '' \
- '
' \
- '' \
- '' \
- '' \
- '' \
- '| 1 | ' \
- ' ' \
- '' \
- '| 2 | ' \
- ' ' \
- ' ' \
- ' | ' \
- '
' \
- '
' \
- '
'
-
+ out_string = call_wsgi_app(server, body_pairs=(("s", "1"), ("s", "2")))
+ # FIXME: Needs a proper test with xpaths and all.
+ show(
+ html.fromstring(out_string), "TestHtmlRowTable.test_string_array_no_header"
+ )
+ assert (
+ out_string.decode("utf8") == ""
+ '
'
+ ""
+ ""
+ ""
+ ""
+ "| 1 | "
+ " "
+ ""
+ "| 2 | "
+ " "
+ " "
+ " | "
+ "
"
+ "
"
+ "
"
+ )
def test_complex_array(self):
v = [
- CM(i=1, s='a'),
- CM(i=2, s='b'),
- CM(i=3, s='c'),
- CM(i=4, s='d'),
+ CM(i=1, s="a"),
+ CM(i=2, s="b"),
+ CM(i=3, s="c"),
+ CM(i=4, s="d"),
]
+
class SomeService(Service):
@srpc(_returns=Array(CM))
def some_call():
return v
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(),
- out_protocol=HtmlRowTable(field_type_name_attr=None))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HtmlRowTable(field_type_name_attr=None),
+ )
server = WsgiApplication(app)
out_string = call_wsgi_app_kwargs(server)
- show(html.fromstring(out_string), 'TestHtmlRowTable.test_complex_array')
- #FIXME: Needs a proper test with xpaths and all.
- assert out_string.decode('utf8') == \
- '' \
- '
' \
- '' \
- '' \
- '| i | ' \
- '1 | ' \
- '
' \
- '' \
- '| s | ' \
- 'a | ' \
- '
' \
- '' \
- '
' \
- '
' \
- '' \
- '' \
- '| i | ' \
- '2 | ' \
- '
' \
- '' \
- '| s | ' \
- 'b | ' \
- '
' \
- '' \
- '
' \
- '
' \
- '' \
- '' \
- '| i | ' \
- '3 | ' \
- '
' \
- '' \
- '| s | ' \
- 'c | ' \
- '
' \
- '' \
- '
' \
- '
' \
- '' \
- '' \
- '| i | ' \
- '4 | ' \
- '
' \
- '' \
- '| s | ' \
- 'd | ' \
- '
' \
- '' \
- '
' \
- '
'
-
-
-
-if __name__ == '__main__':
+ show(html.fromstring(out_string), "TestHtmlRowTable.test_complex_array")
+ # FIXME: Needs a proper test with xpaths and all.
+ assert (
+ out_string.decode("utf8") == ""
+ '
'
+ ""
+ ""
+ '| i | '
+ '1 | '
+ "
"
+ ""
+ '| s | '
+ 'a | '
+ "
"
+ ""
+ "
"
+ '
'
+ ""
+ ""
+ '| i | '
+ '2 | '
+ "
"
+ ""
+ '| s | '
+ 'b | '
+ "
"
+ ""
+ "
"
+ '
'
+ ""
+ ""
+ '| i | '
+ '3 | '
+ "
"
+ ""
+ '| s | '
+ 'c | '
+ "
"
+ ""
+ "
"
+ '
'
+ ""
+ ""
+ '| i | '
+ '4 | '
+ "
"
+ ""
+ '| s | '
+ 'd | '
+ "
"
+ ""
+ "
"
+ "
"
+ )
+
+
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/protocol/test_http.py b/spyne/test/protocol/test_http.py
index 12370ec99..50d7d46ca 100755
--- a/spyne/test/protocol/test_http.py
+++ b/spyne/test/protocol/test_http.py
@@ -20,28 +20,33 @@
import logging
+
logging.basicConfig(level=logging.DEBUG)
import unittest
-
-from spyne.util.six import StringIO
-from spyne.util.six.moves.http_cookies import SimpleCookie
-
from datetime import datetime
+from http.cookies import SimpleCookie
+from io import StringIO
from wsgiref.validate import validator as wsgiref_validator
-from spyne.server.wsgi import _parse_qs
from spyne.application import Application
-from spyne.error import ValidationError
from spyne.const.http import HTTP_200
-from spyne.decorator import rpc
-from spyne.decorator import srpc
-from spyne.model import ByteArray, DateTime, Uuid, String, Integer, Integer8, \
- ComplexModel, Array
-from spyne.protocol.http import HttpRpc, HttpPattern, _parse_cookie
-from spyne.service import Service
-from spyne.server.wsgi import WsgiApplication, WsgiMethodContext
+from spyne.decorator import rpc, srpc
+from spyne.error import ValidationError
+from spyne.model import (
+ Array,
+ ByteArray,
+ ComplexModel,
+ DateTime,
+ Integer,
+ Integer8,
+ String,
+ Uuid,
+)
+from spyne.protocol.http import HttpPattern, HttpRpc, _parse_cookie
from spyne.server.http import HttpTransportContext
+from spyne.server.wsgi import WsgiApplication, WsgiMethodContext, _parse_qs
+from spyne.service import Service
from spyne.util.test import call_wsgi_app_kwargs
@@ -52,27 +57,29 @@ class SomeService(Service):
def echo_string(s):
return s
- app = Application([SomeService], 'tns',
- in_protocol=HttpRpc(validator='soft'),
- out_protocol=HttpRpc(),
- )
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(validator="soft"),
+ out_protocol=HttpRpc(),
+ )
self.app = WsgiApplication(app)
def test_without_content_type(self):
headers = None
- ret = call_wsgi_app_kwargs(self.app, 'echo_string', headers, s="string")
- assert ret == b'string'
+ ret = call_wsgi_app_kwargs(self.app, "echo_string", headers, s="string")
+ assert ret == b"string"
def test_without_encoding(self):
- headers = {'CONTENT_TYPE':'text/plain'}
- ret = call_wsgi_app_kwargs(self.app, 'echo_string', headers, s="string")
- assert ret == b'string'
+ headers = {"CONTENT_TYPE": "text/plain"}
+ ret = call_wsgi_app_kwargs(self.app, "echo_string", headers, s="string")
+ assert ret == b"string"
def test_with_encoding(self):
- headers = {'CONTENT_TYPE':'text/plain; charset=utf8'}
- ret = call_wsgi_app_kwargs(self.app, 'echo_string', headers, s="string")
- assert ret == b'string'
+ headers = {"CONTENT_TYPE": "text/plain; charset=utf8"}
+ ret = call_wsgi_app_kwargs(self.app, "echo_string", headers, s="string")
+ assert ret == b"string"
class TestHttpTransportContext(unittest.TestCase):
@@ -83,42 +90,60 @@ def test_gen_header(self):
class TestSimpleDictDocument(unittest.TestCase):
def test_own_parse_qs_01(self):
- assert dict(_parse_qs('')) == {}
+ assert dict(_parse_qs("")) == {}
+
def test_own_parse_qs_02(self):
- assert dict(_parse_qs('p')) == {'p': [None]}
+ assert dict(_parse_qs("p")) == {"p": [None]}
+
def test_own_parse_qs_03(self):
- assert dict(_parse_qs('p=')) == {'p': ['']}
+ assert dict(_parse_qs("p=")) == {"p": [""]}
+
def test_own_parse_qs_04(self):
- assert dict(_parse_qs('p=1')) == {'p': ['1']}
+ assert dict(_parse_qs("p=1")) == {"p": ["1"]}
+
def test_own_parse_qs_05(self):
- assert dict(_parse_qs('p=1&')) == {'p': ['1']}
+ assert dict(_parse_qs("p=1&")) == {"p": ["1"]}
+
def test_own_parse_qs_06(self):
- assert dict(_parse_qs('p=1&q')) == {'p': ['1'], 'q': [None]}
+ assert dict(_parse_qs("p=1&q")) == {"p": ["1"], "q": [None]}
+
def test_own_parse_qs_07(self):
- assert dict(_parse_qs('p=1&q=')) == {'p': ['1'], 'q': ['']}
+ assert dict(_parse_qs("p=1&q=")) == {"p": ["1"], "q": [""]}
+
def test_own_parse_qs_08(self):
- assert dict(_parse_qs('p=1&q=2')) == {'p': ['1'], 'q': ['2']}
+ assert dict(_parse_qs("p=1&q=2")) == {"p": ["1"], "q": ["2"]}
+
def test_own_parse_qs_09(self):
- assert dict(_parse_qs('p=1&q=2&p')) == {'p': ['1', None], 'q': ['2']}
+ assert dict(_parse_qs("p=1&q=2&p")) == {"p": ["1", None], "q": ["2"]}
+
def test_own_parse_qs_10(self):
- assert dict(_parse_qs('p=1&q=2&p=')) == {'p': ['1', ''], 'q': ['2']}
+ assert dict(_parse_qs("p=1&q=2&p=")) == {"p": ["1", ""], "q": ["2"]}
+
def test_own_parse_qs_11(self):
- assert dict(_parse_qs('p=1&q=2&p=3')) == {'p': ['1', '3'], 'q': ['2']}
+ assert dict(_parse_qs("p=1&q=2&p=3")) == {"p": ["1", "3"], "q": ["2"]}
+
-def _test(services, qs, validator='soft', strict_arrays=False):
- app = Application(services, 'tns',
- in_protocol=HttpRpc(validator=validator, strict_arrays=strict_arrays),
- out_protocol=HttpRpc())
+def _test(services, qs, validator="soft", strict_arrays=False):
+ app = Application(
+ services,
+ "tns",
+ in_protocol=HttpRpc(validator=validator, strict_arrays=strict_arrays),
+ out_protocol=HttpRpc(),
+ )
server = WsgiApplication(app)
- initial_ctx = WsgiMethodContext(server, {
- 'QUERY_STRING': qs,
- 'PATH_INFO': '/some_call',
- 'REQUEST_METHOD': 'GET',
- 'SERVER_NAME': "localhost",
- }, 'some-content-type')
+ initial_ctx = WsgiMethodContext(
+ server,
+ {
+ "QUERY_STRING": qs,
+ "PATH_INFO": "/some_call",
+ "REQUEST_METHOD": "GET",
+ "SERVER_NAME": "localhost",
+ },
+ "some-content-type",
+ )
- ctx, = server.generate_contexts(initial_ctx)
+ (ctx,) = server.generate_contexts(initial_ctx)
server.get_in_object(ctx)
if ctx.in_error is not None:
@@ -132,6 +157,7 @@ def _test(services, qs, validator='soft', strict_arrays=False):
return ctx
+
class TestValidation(unittest.TestCase):
def test_validation_frequency(self):
class SomeService(Service):
@@ -140,7 +166,7 @@ def some_call(p):
pass
try:
- _test([SomeService], '', validator='soft')
+ _test([SomeService], "", validator="soft")
except ValidationError:
pass
else:
@@ -148,12 +174,12 @@ def some_call(p):
def _test_validation_frequency_simple_bare(self):
class SomeService(Service):
- @srpc(ByteArray(min_occurs=1), _body_style='bare', _returns=ByteArray)
+ @srpc(ByteArray(min_occurs=1), _body_style="bare", _returns=ByteArray)
def some_call(p):
pass
try:
- _test([SomeService], '', validator='soft')
+ _test([SomeService], "", validator="soft")
except ValidationError:
pass
else:
@@ -161,20 +187,20 @@ def some_call(p):
def test_validation_frequency_complex_bare_parent(self):
class C(ComplexModel):
- i=Integer(min_occurs=1)
- s=String
+ i = Integer(min_occurs=1)
+ s = String
class SomeService(Service):
- @srpc(C, _body_style='bare')
+ @srpc(C, _body_style="bare")
def some_call(p):
pass
# must not complain about missing s
- _test([SomeService], 'i=5', validator='soft')
+ _test([SomeService], "i=5", validator="soft")
# must raise validation error for missing i
try:
- _test([SomeService], 's=a', validator='soft')
+ _test([SomeService], "s=a", validator="soft")
except ValidationError:
pass
else:
@@ -182,7 +208,7 @@ def some_call(p):
# must raise validation error for missing i
try:
- _test([SomeService], '', validator='soft')
+ _test([SomeService], "", validator="soft")
except ValidationError:
pass
else:
@@ -190,8 +216,8 @@ def some_call(p):
def test_validation_frequency_parent(self):
class C(ComplexModel):
- i=Integer(min_occurs=1)
- s=String
+ i = Integer(min_occurs=1)
+ s = String
class SomeService(Service):
@srpc(C)
@@ -199,22 +225,22 @@ def some_call(p):
pass
# must not complain about missing s
- _test([SomeService], 'p.i=5', validator='soft')
+ _test([SomeService], "p.i=5", validator="soft")
try:
# must raise validation error for missing i
- _test([SomeService], 'p.s=a', validator='soft')
+ _test([SomeService], "p.s=a", validator="soft")
except ValidationError:
pass
else:
raise Exception("must raise ValidationError")
# must not raise anything for missing p because C has min_occurs=0
- _test([SomeService], '', validator='soft')
+ _test([SomeService], "", validator="soft")
def test_validation_array(self):
class C(ComplexModel):
- i=Integer(min_occurs=1)
- s=String
+ i = Integer(min_occurs=1)
+ s = String
class SomeService(Service):
@srpc(Array(C))
@@ -222,21 +248,21 @@ def some_call(p):
pass
# must not complain about missing s
- _test([SomeService], 'p[0].i=5', validator='soft')
+ _test([SomeService], "p[0].i=5", validator="soft")
try:
# must raise validation error for missing i
- _test([SomeService], 'p[0].s=a', validator='soft')
+ _test([SomeService], "p[0].s=a", validator="soft")
except ValidationError:
pass
else:
raise Exception("must raise ValidationError")
# must not raise anything for missing p because C has min_occurs=0
- _test([SomeService], '', validator='soft')
+ _test([SomeService], "", validator="soft")
def test_validation_array_index_jump_error(self):
class C(ComplexModel):
- i=Integer
+ i = Integer
class SomeService(Service):
@srpc(Array(C), _returns=String)
@@ -246,7 +272,7 @@ def some_call(p):
try:
# must raise validation error for index jump from 0 to 2 even without
# any validation
- _test([SomeService], 'p[0].i=42&p[2].i=42&', strict_arrays=True)
+ _test([SomeService], "p[0].i=42&p[2].i=42&", strict_arrays=True)
except ValidationError:
pass
else:
@@ -254,7 +280,7 @@ def some_call(p):
def test_validation_array_index_jump_tolerate(self):
class C(ComplexModel):
- i=Integer
+ i = Integer
class SomeService(Service):
@srpc(Array(C), _returns=String)
@@ -263,12 +289,12 @@ def some_call(p):
# must not raise validation error for index jump from 0 to 2 and ignore
# element with index 1
- ret = _test([SomeService], 'p[0].i=0&p[2].i=2&', strict_arrays=False)
- assert ret.out_object[0] == '[C(i=0), C(i=2)]'
+ ret = _test([SomeService], "p[0].i=0&p[2].i=2&", strict_arrays=False)
+ assert ret.out_object[0] == "[C(i=0), C(i=2)]"
# even if they arrive out-of-order.
- ret = _test([SomeService], 'p[2].i=2&p[0].i=0&', strict_arrays=False)
- assert ret.out_object[0] == '[C(i=0), C(i=2)]'
+ ret = _test([SomeService], "p[2].i=2&p[0].i=0&", strict_arrays=False)
+ assert ret.out_object[0] == "[C(i=0), C(i=2)]"
def test_validation_nested_array(self):
class CC(ComplexModel):
@@ -284,17 +310,17 @@ def some_call(p):
print(p)
# must not complain about missing s
- _test([SomeService], 'p[0].i=5', validator='soft')
+ _test([SomeService], "p[0].i=5", validator="soft")
try:
# must raise validation error for missing i
- _test([SomeService], 'p[0].cc[0].d=2013-01-01', validator='soft')
+ _test([SomeService], "p[0].cc[0].d=2013-01-01", validator="soft")
except ValidationError:
pass
else:
raise Exception("must raise ValidationError")
# must not raise anything for missing p because C has min_occurs=0
- _test([SomeService], '', validator='soft')
+ _test([SomeService], "", validator="soft")
def test_validation_nullable(self):
class SomeService(Service):
@@ -303,7 +329,7 @@ def some_call(p):
pass
try:
- _test([SomeService], 'p', validator='soft')
+ _test([SomeService], "p", validator="soft")
except ValidationError:
pass
else:
@@ -316,7 +342,7 @@ def some_call(p):
pass
try:
- _test([SomeService], "p=duduk", validator='soft')
+ _test([SomeService], "p=duduk", validator="soft")
except ValidationError:
pass
else:
@@ -329,7 +355,7 @@ def some_call(p):
pass
try:
- _test([SomeService], 'p=10', validator='soft')
+ _test([SomeService], "p=10", validator="soft")
except ValidationError:
pass
else:
@@ -342,7 +368,7 @@ def some_call(p):
pass
try:
- _test([SomeService], "p=-129", validator='soft')
+ _test([SomeService], "p=-129", validator="soft")
except ValidationError:
pass
else:
@@ -355,7 +381,7 @@ def some_call(p):
pass
try:
- _test([SomeService], "p=1.2", validator='soft')
+ _test([SomeService], "p=1.2", validator="soft")
except ValidationError:
pass
else:
@@ -367,15 +393,16 @@ def test_multiple_return(self):
class SomeService(Service):
@srpc(_returns=[Integer, String])
def some_call():
- return 1, 's'
+ return 1, "s"
try:
- _test([SomeService], '')
+ _test([SomeService], "")
except TypeError:
pass
else:
- raise Exception("Must fail with: HttpRpc does not support complex "
- "return types.")
+ raise Exception(
+ "Must fail with: HttpRpc does not support complex " "return types."
+ )
def test_primitive_only(self):
class SomeComplexModel(ComplexModel):
@@ -385,15 +412,16 @@ class SomeComplexModel(ComplexModel):
class SomeService(Service):
@srpc(SomeComplexModel, _returns=SomeComplexModel)
def some_call(scm):
- return SomeComplexModel(i=5, s='5x')
+ return SomeComplexModel(i=5, s="5x")
try:
- _test([SomeService], '')
+ _test([SomeService], "")
except TypeError:
pass
else:
- raise Exception("Must fail with: HttpRpc does not support complex "
- "return types.")
+ raise Exception(
+ "Must fail with: HttpRpc does not support complex " "return types."
+ )
def test_complex(self):
class CM(ComplexModel):
@@ -414,18 +442,18 @@ class SomeService(Service):
def some_call(ccm):
return repr(CCM(c=ccm.c, i=ccm.i, s=ccm.s))
- ctx = _test([SomeService], '&ccm.i=1&ccm.s=s&ccm.c.i=3&ccm.c.s=cs')
+ ctx = _test([SomeService], "&ccm.i=1&ccm.s=s&ccm.c.i=3&ccm.c.s=cs")
assert ctx.out_string[0] == b"CCM(i=1, c=CM(i=3, s='cs'), s='s')"
def test_simple_array(self):
class SomeService(Service):
- @srpc(String(max_occurs='unbounded'), _returns=String)
+ @srpc(String(max_occurs="unbounded"), _returns=String)
def some_call(s):
- return '\n'.join(s)
+ return "\n".join(s)
- ctx = _test([SomeService], '&s=1&s=2')
- assert b''.join(ctx.out_string) == b'1\n2'
+ ctx = _test([SomeService], "&s=1&s=2")
+ assert b"".join(ctx.out_string) == b"1\n2"
def test_complex_array(self):
class CM(ComplexModel):
@@ -437,17 +465,18 @@ class CM(ComplexModel):
class SomeService(Service):
@srpc(Array(CM), _returns=String)
def some_call(cs):
- return '\n'.join([repr(c) for c in cs])
+ return "\n".join([repr(c) for c in cs])
- ctx = _test([SomeService],
- 'cs[0].i=1&cs[0].s=x'
- '&cs[1].i=2&cs[1].s=y'
- '&cs[2].i=3&cs[2].s=z')
+ ctx = _test(
+ [SomeService],
+ "cs[0].i=1&cs[0].s=x" "&cs[1].i=2&cs[1].s=y" "&cs[2].i=3&cs[2].s=z",
+ )
- assert b''.join(ctx.out_string) == \
- b"CM(i=1, s='x')\n" \
- b"CM(i=2, s='y')\n" \
- b"CM(i=3, s='z')"
+ assert (
+ b"".join(ctx.out_string) == b"CM(i=1, s='x')\n"
+ b"CM(i=2, s='y')\n"
+ b"CM(i=3, s='z')"
+ )
def test_complex_array_empty(self):
class CM(ComplexModel):
@@ -461,9 +490,9 @@ class SomeService(Service):
def some_call(cs):
return repr(cs)
- ctx = _test([SomeService], 'cs=empty')
+ ctx = _test([SomeService], "cs=empty")
- assert b''.join(ctx.out_string) == b'[]'
+ assert b"".join(ctx.out_string) == b"[]"
def test_complex_object_empty(self):
class CM(ComplexModel):
@@ -477,9 +506,9 @@ class SomeService(Service):
def some_call(c):
return repr(c)
- ctx = _test([SomeService], 'c=empty')
+ ctx = _test([SomeService], "c=empty")
- assert b''.join(ctx.out_string) == b'CM()'
+ assert b"".join(ctx.out_string) == b"CM()"
def test_nested_flatten(self):
class CM(ComplexModel):
@@ -500,10 +529,10 @@ class SomeService(Service):
def some_call(ccm):
return repr(ccm)
- ctx = _test([SomeService], '&ccm.i=1&ccm.s=s&ccm.c.i=3&ccm.c.s=cs')
+ ctx = _test([SomeService], "&ccm.i=1&ccm.s=s&ccm.c.i=3&ccm.c.s=cs")
print(ctx.out_string)
- assert b''.join(ctx.out_string) == b"CCM(i=1, c=CM(i=3, s='cs'), s='s')"
+ assert b"".join(ctx.out_string) == b"CCM(i=1, c=CM(i=3, s='cs'), s='s')"
def test_nested_flatten_with_multiple_values_1(self):
class CM(ComplexModel):
@@ -524,11 +553,14 @@ class SomeService(Service):
def some_call(ccm):
return repr(ccm)
- ctx = _test([SomeService], 'ccm[0].i=1&ccm[0].s=s'
- '&ccm[0].c.i=1&ccm[0].c.s=a'
- '&ccm[1].c.i=2&ccm[1].c.s=b')
+ ctx = _test(
+ [SomeService],
+ "ccm[0].i=1&ccm[0].s=s"
+ "&ccm[0].c.i=1&ccm[0].c.s=a"
+ "&ccm[1].c.i=2&ccm[1].c.s=b",
+ )
- s = b''.join(ctx.out_string)
+ s = b"".join(ctx.out_string)
assert s == b"[CCM(i=1, c=CM(i=1, s='a'), s='s'), CCM(c=CM(i=2, s='b'))]"
@@ -551,11 +583,12 @@ class SomeService(Service):
def some_call(ccm):
return repr(ccm)
- ctx = _test([SomeService], 'ccm.i=1&ccm.s=s'
- '&ccm.c[0].i=1&ccm.c[0].s=a'
- '&ccm.c[1].i=2&ccm.c[1].s=b')
+ ctx = _test(
+ [SomeService],
+ "ccm.i=1&ccm.s=s" "&ccm.c[0].i=1&ccm.c[0].s=a" "&ccm.c[1].i=2&ccm.c[1].s=b",
+ )
- s = b''.join(list(ctx.out_string))
+ s = b"".join(list(ctx.out_string))
assert s == b"CCM(i=1, c=[CM(i=1, s='a'), CM(i=2, s='b')], s='s')"
def test_nested_flatten_with_complex_array(self):
@@ -577,11 +610,12 @@ class SomeService(Service):
def some_call(ccm):
return repr(ccm)
- ctx = _test([SomeService], 'ccm.i=1&ccm.s=s'
- '&ccm.c[0].i=1&ccm.c[0].s=a'
- '&ccm.c[1].i=2&ccm.c[1].s=b')
+ ctx = _test(
+ [SomeService],
+ "ccm.i=1&ccm.s=s" "&ccm.c[0].i=1&ccm.c[0].s=a" "&ccm.c[1].i=2&ccm.c[1].s=b",
+ )
- s = b''.join(list(ctx.out_string))
+ s = b"".join(list(ctx.out_string))
assert s == b"CCM(i=1, c=[CM(i=1, s='a'), CM(i=2, s='b')], s='s')"
def test_nested_2_flatten_with_primitive_array(self):
@@ -597,17 +631,15 @@ class SomeService(Service):
def some_call(ccm):
return repr(ccm)
- ctx = _test([SomeService], 'ccm[0].i=1&ccm[0].s=s'
- '&ccm[0].c=a'
- '&ccm[0].c=b')
- s = b''.join(list(ctx.out_string))
+ ctx = _test([SomeService], "ccm[0].i=1&ccm[0].s=s" "&ccm[0].c=a" "&ccm[0].c=b")
+ s = b"".join(list(ctx.out_string))
assert s == b"[CCM(i=1, c=['a', 'b'], s='s')]"
def test_default(self):
class CM(ComplexModel):
_type_info = [
("i", Integer),
- ("s", String(default='default')),
+ ("s", String(default="default")),
]
class SomeService(Service):
@@ -616,18 +648,18 @@ def some_call(cm):
return repr(cm)
# s is missing
- ctx = _test([SomeService], 'cm.i=1')
- s = b''.join(ctx.out_string)
+ ctx = _test([SomeService], "cm.i=1")
+ s = b"".join(ctx.out_string)
assert s == b"CM(i=1, s='default')"
# s is None
- ctx = _test([SomeService], 'cm.i=1&cm.s')
- s = b''.join(ctx.out_string)
+ ctx = _test([SomeService], "cm.i=1&cm.s")
+ s = b"".join(ctx.out_string)
assert s == b"CM(i=1)"
# s is empty
- ctx = _test([SomeService], 'cm.i=1&cm.s=')
- s = b''.join(ctx.out_string)
+ ctx = _test([SomeService], "cm.i=1&cm.s=")
+ s = b"".join(ctx.out_string)
assert s == b"CM(i=1, s='')"
def test_nested_flatten_with_primitive_array(self):
@@ -643,34 +675,26 @@ class SomeService(Service):
def some_call(ccm):
return repr(ccm)
- ctx = _test([SomeService], 'ccm.i=1&ccm.s=s'
- '&ccm.c=a'
- '&ccm.c=b')
- s = b''.join(list(ctx.out_string))
+ ctx = _test([SomeService], "ccm.i=1&ccm.s=s" "&ccm.c=a" "&ccm.c=b")
+ s = b"".join(list(ctx.out_string))
assert s == b"CCM(i=1, c=['a', 'b'], s='s')"
- ctx = _test([SomeService], 'ccm.i=1'
- '&ccm.s=s'
- '&ccm.c[1]=b'
- '&ccm.c[0]=a')
- s = b''.join(list(ctx.out_string))
+ ctx = _test([SomeService], "ccm.i=1" "&ccm.s=s" "&ccm.c[1]=b" "&ccm.c[0]=a")
+ s = b"".join(list(ctx.out_string))
assert s == b"CCM(i=1, c=['a', 'b'], s='s')"
- ctx = _test([SomeService], 'ccm.i=1'
- '&ccm.s=s'
- '&ccm.c[0]=a'
- '&ccm.c[1]=b')
- s = b''.join(list(ctx.out_string))
+ ctx = _test([SomeService], "ccm.i=1" "&ccm.s=s" "&ccm.c[0]=a" "&ccm.c[1]=b")
+ s = b"".join(list(ctx.out_string))
assert s == b"CCM(i=1, c=['a', 'b'], s='s')"
def test_http_headers(self):
d = datetime(year=2013, month=1, day=1)
- string = ['hey', 'yo']
+ string = ["hey", "yo"]
class ResponseHeader(ComplexModel):
_type_info = {
- 'Set-Cookie': String(max_occurs='unbounded'),
- 'Expires': DateTime
+ "Set-Cookie": String(max_occurs="unbounded"),
+ "Expires": DateTime,
}
class SomeService(Service):
@@ -679,33 +703,34 @@ class SomeService(Service):
@rpc(String)
def some_call(ctx, s):
assert s is not None
- ctx.out_header = ResponseHeader(**{'Set-Cookie': string,
- 'Expires': d})
+ ctx.out_header = ResponseHeader(**{"Set-Cookie": string, "Expires": d})
def start_response(code, headers):
print(headers)
- assert len([s for s in string
- if ('Set-Cookie', s) in headers]) == len(string)
- assert dict(headers)['Expires'] == 'Tue, 01 Jan 2013 00:00:00 GMT'
+ assert len([s for s in string if ("Set-Cookie", s) in headers]) == len(
+ string
+ )
+ assert dict(headers)["Expires"] == "Tue, 01 Jan 2013 00:00:00 GMT"
- app = Application([SomeService], 'tns',
- in_protocol=HttpRpc(), out_protocol=HttpRpc())
+ app = Application(
+ [SomeService], "tns", in_protocol=HttpRpc(), out_protocol=HttpRpc()
+ )
wsgi_app = WsgiApplication(app)
req_dict = {
- 'SCRIPT_NAME': '',
- 'QUERY_STRING': '&s=foo',
- 'PATH_INFO': '/some_call',
- 'REQUEST_METHOD': 'GET',
- 'SERVER_NAME': 'localhost',
- 'SERVER_PORT': "9999",
- 'wsgi.url_scheme': 'http',
- 'wsgi.version': (1,0),
- 'wsgi.input': StringIO(),
- 'wsgi.errors': StringIO(),
- 'wsgi.multithread': False,
- 'wsgi.multiprocess': False,
- 'wsgi.run_once': True,
+ "SCRIPT_NAME": "",
+ "QUERY_STRING": "&s=foo",
+ "PATH_INFO": "/some_call",
+ "REQUEST_METHOD": "GET",
+ "SERVER_NAME": "localhost",
+ "SERVER_PORT": "9999",
+ "wsgi.url_scheme": "http",
+ "wsgi.version": (1, 0),
+ "wsgi.input": StringIO(),
+ "wsgi.errors": StringIO(),
+ "wsgi.multithread": False,
+ "wsgi.multiprocess": False,
+ "wsgi.run_once": True,
}
ret = wsgi_app(req_dict, start_response)
@@ -714,37 +739,44 @@ def start_response(code, headers):
wsgi_app = wsgiref_validator(wsgi_app)
ret = wsgi_app(req_dict, start_response)
-
- assert list(ret) == [b'']
+ try:
+ assert list(ret) == [b""]
+ finally:
+ ret.close()
class TestHttpPatterns(unittest.TestCase):
def test_rules(self):
_int = 5
- _fragment = 'some_fragment'
+ _fragment = "some_fragment"
class SomeService(Service):
- @srpc(Integer, _returns=Integer, _patterns=[
- HttpPattern('/%s/' % _fragment)])
+ @srpc(
+ Integer,
+ _returns=Integer,
+ _patterns=[HttpPattern("/%s/" % _fragment)],
+ )
def some_call(some_int):
assert some_int == _int
- app = Application([SomeService], 'tns', in_protocol=HttpRpc(), out_protocol=HttpRpc())
+ app = Application(
+ [SomeService], "tns", in_protocol=HttpRpc(), out_protocol=HttpRpc()
+ )
server = WsgiApplication(app)
environ = {
- 'QUERY_STRING': '',
- 'PATH_INFO': '/%s/%d' % (_fragment, _int),
- 'SERVER_PATH':"/",
- 'SERVER_NAME': "localhost",
- 'wsgi.url_scheme': 'http',
- 'SERVER_PORT': '9000',
- 'REQUEST_METHOD': 'GET',
+ "QUERY_STRING": "",
+ "PATH_INFO": "/%s/%d" % (_fragment, _int),
+ "SERVER_PATH": "/",
+ "SERVER_NAME": "localhost",
+ "wsgi.url_scheme": "http",
+ "SERVER_PORT": "9000",
+ "REQUEST_METHOD": "GET",
}
- initial_ctx = WsgiMethodContext(server, environ, 'some-content-type')
+ initial_ctx = WsgiMethodContext(server, environ, "some-content-type")
- ctx, = server.generate_contexts(initial_ctx)
+ (ctx,) = server.generate_contexts(initial_ctx)
foo = []
for i in server._http_patterns:
@@ -763,7 +795,8 @@ def some_call(some_int):
class ParseCookieTest(unittest.TestCase):
def test_cookie_parse(self):
- string = 'some_string'
+ string = "some_string"
+
class RequestHeader(ComplexModel):
some_field = String
@@ -777,37 +810,44 @@ def some_call(ctx, s):
def start_response(code, headers):
assert code == HTTP_200
- c = 'some_field=%s'% (string,)
+ c = "some_field=%s" % (string,)
- app = Application([SomeService], 'tns',
- in_protocol=HttpRpc(parse_cookie=True), out_protocol=HttpRpc())
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=HttpRpc(parse_cookie=True),
+ out_protocol=HttpRpc(),
+ )
wsgi_app = WsgiApplication(app)
req_dict = {
- 'SCRIPT_NAME': '',
- 'QUERY_STRING': '',
- 'PATH_INFO': '/some_call',
- 'REQUEST_METHOD': 'GET',
- 'SERVER_NAME': 'localhost',
- 'SERVER_PORT': "9999",
- 'HTTP_COOKIE': c,
- 'wsgi.url_scheme': 'http',
- 'wsgi.version': (1,0),
- 'wsgi.input': StringIO(),
- 'wsgi.errors': StringIO(),
- 'wsgi.multithread': False,
- 'wsgi.multiprocess': False,
- 'wsgi.run_once': True,
+ "SCRIPT_NAME": "",
+ "QUERY_STRING": "",
+ "PATH_INFO": "/some_call",
+ "REQUEST_METHOD": "GET",
+ "SERVER_NAME": "localhost",
+ "SERVER_PORT": "9999",
+ "HTTP_COOKIE": c,
+ "wsgi.url_scheme": "http",
+ "wsgi.version": (1, 0),
+ "wsgi.input": StringIO(),
+ "wsgi.errors": StringIO(),
+ "wsgi.multithread": False,
+ "wsgi.multiprocess": False,
+ "wsgi.run_once": True,
}
ret = wsgi_app(req_dict, start_response)
- print(ret)
+ list(ret)
wsgi_app = wsgiref_validator(wsgi_app)
ret = wsgi_app(req_dict, start_response)
- print(ret)
+ try:
+ list(ret)
+ finally:
+ ret.close()
# These tests copied from Django:
# https://github.com/django/django/pull/6277/commits/da810901ada1cae9fc1f018f879f11a7fb467b28
@@ -815,26 +855,37 @@ def test_python_cookies(self):
"""
Test cases copied from Python's Lib/test/test_http_cookies.py
"""
- self.assertEqual(_parse_cookie('chips=ahoy; vienna=finger'), {'chips': 'ahoy', 'vienna': 'finger'})
+ self.assertEqual(
+ _parse_cookie("chips=ahoy; vienna=finger"),
+ {"chips": "ahoy", "vienna": "finger"},
+ )
# Here _parse_cookie() differs from Python's cookie parsing in that it
# treats all semicolons as delimiters, even within quotes.
self.assertEqual(
_parse_cookie('keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"'),
- {'keebler': '"E=mc2', 'L': '\\"Loves\\"', 'fudge': '\\012', '': '"'}
+ {"keebler": '"E=mc2', "L": '\\"Loves\\"', "fudge": "\\012", "": '"'},
)
# Illegal cookies that have an '=' char in an unquoted value.
- self.assertEqual(_parse_cookie('keebler=E=mc2'), {'keebler': 'E=mc2'})
+ self.assertEqual(_parse_cookie("keebler=E=mc2"), {"keebler": "E=mc2"})
# Cookies with ':' character in their name.
- self.assertEqual(_parse_cookie('key:term=value:term'), {'key:term': 'value:term'})
+ self.assertEqual(
+ _parse_cookie("key:term=value:term"), {"key:term": "value:term"}
+ )
# Cookies with '[' and ']'.
- self.assertEqual(_parse_cookie('a=b; c=[; d=r; f=h'), {'a': 'b', 'c': '[', 'd': 'r', 'f': 'h'})
+ self.assertEqual(
+ _parse_cookie("a=b; c=[; d=r; f=h"),
+ {"a": "b", "c": "[", "d": "r", "f": "h"},
+ )
def test_cookie_edgecases(self):
# Cookies that RFC6265 allows.
- self.assertEqual(_parse_cookie('a=b; Domain=example.com'), {'a': 'b', 'Domain': 'example.com'})
+ self.assertEqual(
+ _parse_cookie("a=b; Domain=example.com"),
+ {"a": "b", "Domain": "example.com"},
+ )
# _parse_cookie() has historically kept only the last cookie with the
# same name.
- self.assertEqual(_parse_cookie('a=b; h=i; a=c'), {'a': 'c', 'h': 'i'})
+ self.assertEqual(_parse_cookie("a=b; h=i; a=c"), {"a": "c", "h": "i"})
def test_invalid_cookies(self):
"""
@@ -843,26 +894,32 @@ def test_invalid_cookies(self):
"""
# Chunks without an equals sign appear as unnamed values per
# https://bugzilla.mozilla.org/show_bug.cgi?id=169091
- self.assertIn('django_language',
- _parse_cookie('abc=def; unnamed; django_language=en').keys())
+ self.assertIn(
+ "django_language",
+ _parse_cookie("abc=def; unnamed; django_language=en").keys(),
+ )
# Even a double quote may be an unamed value.
- self.assertEqual(
- _parse_cookie('a=b; "; c=d'), {'a': 'b', '': '"', 'c': 'd'})
+ self.assertEqual(_parse_cookie('a=b; "; c=d'), {"a": "b", "": '"', "c": "d"})
# Spaces in names and values, and an equals sign in values.
- self.assertEqual(_parse_cookie('a b c=d e = f; gh=i'),
- {'a b c': 'd e = f', 'gh': 'i'})
+ self.assertEqual(
+ _parse_cookie("a b c=d e = f; gh=i"), {"a b c": "d e = f", "gh": "i"}
+ )
# More characters the spec forbids.
- self.assertEqual(_parse_cookie('a b,c<>@:/[]?{}=d " =e,f g'),
- {'a b,c<>@:/[]?{}': 'd " =e,f g'})
+ self.assertEqual(
+ _parse_cookie('a b,c<>@:/[]?{}=d " =e,f g'),
+ {"a b,c<>@:/[]?{}": 'd " =e,f g'},
+ )
# Unicode characters. The spec only allows ASCII.
- self.assertEqual(_parse_cookie(u'saint=André Bessette'),
- {u'saint': u'André Bessette'})
+ self.assertEqual(
+ _parse_cookie("saint=André Bessette"), {"saint": "André Bessette"}
+ )
# Browsers don't send extra whitespace or semicolons in Cookie headers,
# but _parse_cookie() should parse whitespace the same way
# document.cookie parses whitespace.
- self.assertEqual(_parse_cookie(' = b ; ; = ; c = ; '),
- {'': 'b', 'c': ''})
+ self.assertEqual(
+ _parse_cookie(" = b ; ; = ; c = ; "), {"": "b", "c": ""}
+ )
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/protocol/test_json.py b/spyne/test/protocol/test_json.py
index ac162fb0f..589e1e6dc 100755
--- a/spyne/test/protocol/test_json.py
+++ b/spyne/test/protocol/test_json.py
@@ -18,38 +18,33 @@
#
import unittest
+
try:
import simplejson as json
except ImportError:
import json
-
-from spyne import MethodContext
-from spyne import Application
-from spyne import rpc,srpc
-from spyne import Service
-from spyne.model import Integer, Unicode, ComplexModel
-from spyne.protocol.json import JsonP
-from spyne.protocol.json import JsonDocument
-from spyne.protocol.json import JsonEncoder
-from spyne.protocol.json import _SpyneJsonRpc1
+from spyne import Application, MethodContext, Service, rpc, srpc
+from spyne.model import ComplexModel, Integer, Unicode
+from spyne.protocol.json import JsonDocument, JsonEncoder, JsonP, _SpyneJsonRpc1
from spyne.server import ServerBase
from spyne.server.null import NullServer
+from spyne.test.protocol._test_dictdoc import TDictDocumentTest, TDry
-from spyne.test.protocol._test_dictdoc import TDictDocumentTest
-from spyne.test.protocol._test_dictdoc import TDry
-
-class TestDictDocument(TDictDocumentTest(json, JsonDocument,
- dumps_kwargs=dict(cls=JsonEncoder))):
+class TestDictDocument(
+ TDictDocumentTest(json, JsonDocument, dumps_kwargs=dict(cls=JsonEncoder))
+):
def dumps(self, o):
- return super(TestDictDocument, self).dumps(o).encode('utf8')
+ return super(TestDictDocument, self).dumps(o).encode("utf8")
def loads(self, o):
- return super(TestDictDocument, self).loads(o.decode('utf8'))
+ return super(TestDictDocument, self).loads(o.decode("utf8"))
+
_dry_sjrpc1 = TDry(json, _SpyneJsonRpc1)
+
class TestSpyneJsonRpc1(unittest.TestCase):
def test_call(self):
class SomeService(Service):
@@ -58,8 +53,7 @@ def yay(i):
print(i)
return i
- ctx = _dry_sjrpc1([SomeService],
- {"ver": 1, "body": {"yay": {"i":5}}}, True)
+ ctx = _dry_sjrpc1([SomeService], {"ver": 1, "body": {"yay": {"i": 5}}}, True)
print(ctx)
print(list(ctx.out_string))
@@ -71,13 +65,15 @@ class SomeHeader(ComplexModel):
class SomeService(Service):
__in_header__ = SomeHeader
+
@rpc(Integer, _returns=Integer)
def yay(ctx, i):
print(ctx.in_header)
return ctx.in_header.i
- ctx = _dry_sjrpc1([SomeService],
- {"ver": 1, "body": {"yay": None}, "head": {"i":5}}, True)
+ ctx = _dry_sjrpc1(
+ [SomeService], {"ver": 1, "body": {"yay": None}, "head": {"i": 5}}, True
+ )
print(ctx)
print(list(ctx.out_string))
@@ -89,17 +85,19 @@ class SomeHeader(ComplexModel):
class SomeService(Service):
__in_header__ = SomeHeader
+
@rpc(Integer, Integer, _returns=Integer)
def div(ctx, dividend, divisor):
return dividend / divisor
- ctx = _dry_sjrpc1([SomeService],
- {"ver": 1, "body": {"div": [4,0]}}, True)
+ ctx = _dry_sjrpc1([SomeService], {"ver": 1, "body": {"div": [4, 0]}}, True)
print(ctx)
print(list(ctx.out_string))
- assert ctx.out_document == {"ver": 1, "fault": {
- 'faultcode': 'Server', 'faultstring': 'Internal Error'}}
+ assert ctx.out_document == {
+ "ver": 1,
+ "fault": {"faultcode": "Server", "faultstring": "Internal Error"},
+ }
class TestJsonDocument(unittest.TestCase):
@@ -109,46 +107,55 @@ class SomeService(Service):
def yay():
pass
- app = Application([SomeService], 'tns',
- in_protocol=JsonDocument(),
- out_protocol=JsonDocument())
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=JsonDocument(),
+ out_protocol=JsonDocument(),
+ )
- assert 'cls' in app.out_protocol.kwargs
- assert not ('cls' in app.in_protocol.kwargs)
+ assert "cls" in app.out_protocol.kwargs
+ assert not ("cls" in app.in_protocol.kwargs)
- app = Application([SomeService], 'tns',
- in_protocol=JsonDocument(),
- out_protocol=JsonDocument(cls='hey'))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=JsonDocument(),
+ out_protocol=JsonDocument(cls="hey"),
+ )
- assert app.out_protocol.kwargs['cls'] == 'hey'
- assert not ('cls' in app.in_protocol.kwargs)
+ assert app.out_protocol.kwargs["cls"] == "hey"
+ assert not ("cls" in app.in_protocol.kwargs)
def test_invalid_input(self):
class SomeService(Service):
pass
- app = Application([SomeService], 'tns',
- in_protocol=JsonDocument(),
- out_protocol=JsonDocument())
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=JsonDocument(),
+ out_protocol=JsonDocument(),
+ )
server = ServerBase(app)
initial_ctx = MethodContext(server, MethodContext.SERVER)
- initial_ctx.in_string = [b'{']
- ctx, = server.generate_contexts(initial_ctx, in_string_charset='utf8')
- assert ctx.in_error.faultcode == 'Client.JsonDecodeError'
+ initial_ctx.in_string = [b"{"]
+ (ctx,) = server.generate_contexts(initial_ctx, in_string_charset="utf8")
+ assert ctx.in_error.faultcode == "Client.JsonDecodeError"
class TestJsonP(unittest.TestCase):
def test_callback_name(self):
- callback_name = 'some_callback'
+ callback_name = "some_callback"
class SomeComplexModel(ComplexModel):
i = Integer
s = Unicode
v1 = 42
- v2 = SomeComplexModel(i=42, s='foo')
+ v2 = SomeComplexModel(i=42, s="foo")
class SomeService(Service):
@srpc(_returns=Integer)
@@ -159,54 +166,68 @@ def yay():
def complex():
return v2
- app = Application([SomeService], 'tns',
- in_protocol=JsonDocument(),
- out_protocol=JsonP(callback_name))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=JsonDocument(),
+ out_protocol=JsonP(callback_name),
+ )
server = NullServer(app, ostr=True)
ret = server.service.yay()
ret = list(ret)
- print(b''.join(ret))
- assert b''.join(ret) == b''.join((callback_name.encode('utf8'), b'(',
- str(v1).encode('utf8'), b');'))
+ print(b"".join(ret))
+ assert b"".join(ret) == b"".join(
+ (callback_name.encode("utf8"), b"(", str(v1).encode("utf8"), b");")
+ )
ret = server.service.complex()
ret = list(ret)
- print(b''.join(ret))
- assert b''.join(ret) == b''.join((callback_name.encode('utf8'), b'(',
- json.dumps({"i": 42, "s": "foo"}).encode('utf-8') , b');'))
-
+ print(b"".join(ret))
+ assert b"".join(ret) == b"".join(
+ (
+ callback_name.encode("utf8"),
+ b"(",
+ json.dumps({"i": 42, "s": "foo"}).encode("utf-8"),
+ b");",
+ )
+ )
def test_wrapped_array_in_wrapped_response(self):
- from spyne.model.complex import ComplexModel, Array
+ from spyne.model.complex import Array, ComplexModel
from spyne.model.primitive import Unicode
class Permission(ComplexModel):
_type_info = [
- ('application', Unicode),
- ('feature', Unicode),
+ ("application", Unicode),
+ ("feature", Unicode),
]
class SomeService(Service):
@srpc(_returns=Array(Permission))
def yay():
return [
- Permission(application='app', feature='f1'),
- Permission(application='app', feature='f2')
+ Permission(application="app", feature="f1"),
+ Permission(application="app", feature="f2"),
]
- app = Application([SomeService], 'tns',
- in_protocol=JsonDocument(),
- out_protocol=JsonDocument(ignore_wrappers=False))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=JsonDocument(),
+ out_protocol=JsonDocument(ignore_wrappers=False),
+ )
server = NullServer(app, ostr=True)
- retstr = b''.join(server.service.yay()).decode('utf-8')
+ retstr = b"".join(server.service.yay()).decode("utf-8")
print(retstr)
- assert retstr == '{"yayResponse": {"yayResult": [' \
- '{"Permission": {"application": "app", "feature": "f1"}}, ' \
+ assert (
+ retstr == '{"yayResponse": {"yayResult": ['
+ '{"Permission": {"application": "app", "feature": "f1"}}, '
'{"Permission": {"application": "app", "feature": "f2"}}]}}'
+ )
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/protocol/test_msgpack.py b/spyne/test/protocol/test_msgpack.py
index aa9889235..3331ca760 100755
--- a/spyne/test/protocol/test_msgpack.py
+++ b/spyne/test/protocol/test_msgpack.py
@@ -19,51 +19,45 @@
import logging
-from spyne.util import six
-
logging.basicConfig(level=logging.DEBUG)
import unittest
+from io import BytesIO
import msgpack
from spyne import MethodContext
from spyne.application import Application
-from spyne.decorator import rpc
-from spyne.decorator import srpc
-from spyne.service import Service
-from spyne.model.complex import Array
-from spyne.model.primitive import String
-from spyne.model.complex import ComplexModel
-from spyne.model.primitive import Unicode
-from spyne.protocol.msgpack import MessagePackDocument
-from spyne.protocol.msgpack import MessagePackRpc
-from spyne.util.six import BytesIO
+from spyne.decorator import rpc, srpc
+from spyne.model.complex import Array, ComplexModel
+from spyne.model.primitive import String, Unicode
+from spyne.protocol.msgpack import MessagePackDocument, MessagePackRpc
from spyne.server import ServerBase
from spyne.server.wsgi import WsgiApplication
+from spyne.service import Service
from spyne.test.protocol._test_dictdoc import TDictDocumentTest
-
from spyne.test.test_service import start_response
def convert_dict(d):
- if isinstance(d, six.text_type):
- return d.encode('utf8')
-
if not isinstance(d, dict):
return d
r = {}
for k, v in d.items():
- r[k.encode('utf8')] = convert_dict(v)
+ r[k.encode("utf8")] = convert_dict(v)
return r
# apply spyne defaults to test unpacker
-TestMessagePackDocument = TDictDocumentTest(msgpack, MessagePackDocument,
- loads_kwargs=dict(use_list=False), convert_dict=convert_dict)
+TestMessagePackDocument = TDictDocumentTest(
+ msgpack,
+ MessagePackDocument,
+ loads_kwargs=dict(use_list=False),
+ convert_dict=convert_dict,
+)
class TestMessagePackRpc(unittest.TestCase):
@@ -73,74 +67,88 @@ class SomeService(Service):
def yay():
pass
- app = Application([SomeService], 'tns',
- in_protocol=MessagePackDocument(),
- out_protocol=MessagePackDocument())
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=MessagePackDocument(),
+ out_protocol=MessagePackDocument(),
+ )
server = ServerBase(app)
initial_ctx = MethodContext(server, MethodContext.SERVER)
- initial_ctx.in_string = [b'\xdf'] # Invalid input
- ctx, = server.generate_contexts(initial_ctx)
- assert ctx.in_error.faultcode == 'Client.MessagePackDecodeError'
+ initial_ctx.in_string = [b"\xdf"] # Invalid input
+ (ctx,) = server.generate_contexts(initial_ctx)
+ assert ctx.in_error.faultcode == "Client.MessagePackDecodeError"
def test_rpc(self):
- data = {"a":"b", "c": "d"}
+ data = {"a": "b", "c": "d"}
class KeyValuePair(ComplexModel):
key = Unicode
value = Unicode
class SomeService(Service):
- @rpc(String(max_occurs='unbounded'),
- _returns=Array(KeyValuePair),
- _in_variable_names={
- 'keys': 'key'
- }
- )
+ @rpc(
+ String(max_occurs="unbounded"),
+ _returns=Array(KeyValuePair),
+ _in_variable_names={"keys": "key"},
+ )
def get_values(ctx, keys):
for k in keys:
yield KeyValuePair(key=k, value=data[k])
- application = Application([SomeService],
+ application = Application(
+ [SomeService],
in_protocol=MessagePackRpc(),
out_protocol=MessagePackRpc(ignore_wrappers=False),
- name='Service', tns='tns')
+ name="Service",
+ tns="tns",
+ )
server = WsgiApplication(application)
input_string = msgpack.packb([0, 0, "get_values", [["a", "c"]]])
input_stream = BytesIO(input_string)
- ret = server({
- 'CONTENT_LENGTH': str(len(input_string)),
- 'CONTENT_TYPE': 'application/x-msgpack',
- 'HTTP_CONNECTION': 'close',
- 'HTTP_CONTENT_LENGTH': str(len(input_string)),
- 'HTTP_CONTENT_TYPE': 'application/x-msgpack',
- 'PATH_INFO': '/',
- 'QUERY_STRING': '',
- 'SERVER_NAME': 'localhost',
- 'SERVER_PORT': '7000',
- 'REQUEST_METHOD': 'POST',
- 'wsgi.url_scheme': 'http',
- 'wsgi.input': input_stream,
- }, start_response)
-
- ret = b''.join(ret)
+ ret = server(
+ {
+ "CONTENT_LENGTH": str(len(input_string)),
+ "CONTENT_TYPE": "application/x-msgpack",
+ "HTTP_CONNECTION": "close",
+ "HTTP_CONTENT_LENGTH": str(len(input_string)),
+ "HTTP_CONTENT_TYPE": "application/x-msgpack",
+ "PATH_INFO": "/",
+ "QUERY_STRING": "",
+ "SERVER_NAME": "localhost",
+ "SERVER_PORT": "7000",
+ "REQUEST_METHOD": "POST",
+ "wsgi.url_scheme": "http",
+ "wsgi.input": input_stream,
+ },
+ start_response,
+ )
+
+ ret = b"".join(ret)
print(repr(ret))
ret = msgpack.unpackb(ret)
print(repr(ret))
- s = [1, 0, None, {b'get_valuesResponse': {
- b'get_valuesResult': [
- {b"KeyValuePair": {b'key': b'a', b'value': b'b'}},
- {b"KeyValuePair": {b'key': b'c', b'value': b'd'}},
- ]
- }}
+ s = [
+ 1,
+ 0,
+ None,
+ {
+ b"get_valuesResponse": {
+ b"get_valuesResult": [
+ {b"KeyValuePair": {b"key": "a", b"value": "b"}},
+ {b"KeyValuePair": {b"key": "c", b"value": "d"}},
+ ]
+ }
+ },
]
print(s)
assert ret == s
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/protocol/test_soap11.py b/spyne/test/protocol/test_soap11.py
index 93af58ae9..7dd330887 100755
--- a/spyne/test/protocol/test_soap11.py
+++ b/spyne/test/protocol/test_soap11.py
@@ -24,29 +24,21 @@
import datetime
import unittest
-from lxml import etree
import pytz
+from lxml import etree
from spyne import MethodContext
from spyne.application import Application
from spyne.decorator import rpc
from spyne.interface.wsdl import Wsdl11
-from spyne.model.complex import Array
-from spyne.model.complex import ComplexModel
-from spyne.model.primitive import Unicode
-from spyne.model.primitive import DateTime, Date
-from spyne.model.primitive import Float
-from spyne.model.primitive import Integer
-from spyne.model.primitive import String
+from spyne.model.complex import Array, ComplexModel
from spyne.model.fault import Fault
-from spyne.protocol.soap import Soap11
-from spyne.service import Service
+from spyne.model.primitive import Date, DateTime, Float, Integer, String, Unicode
+from spyne.protocol.soap import Soap11, _from_soap, _parse_xml_string
from spyne.server import ServerBase
+from spyne.service import Service
-from spyne.protocol.soap import _from_soap
-from spyne.protocol.soap import _parse_xml_string
-
-Application.transport = 'test'
+Application.transport = "test"
def start_response(code, headers):
@@ -63,6 +55,7 @@ class Address(ComplexModel):
laditude = Float
longitude = Float
+
class Person(ComplexModel):
__namespace__ = "TestService"
@@ -72,34 +65,40 @@ class Person(ComplexModel):
addresses = Array(Address)
titles = Array(String)
+
class Request(ComplexModel):
__namespace__ = "TestService"
param1 = String
param2 = Integer
+
class Response(ComplexModel):
__namespace__ = "TestService"
param1 = Float
+
class TypeNS1(ComplexModel):
__namespace__ = "TestService.NS1"
s = String
i = Integer
+
class TypeNS2(ComplexModel):
__namespace__ = "TestService.NS2"
d = DateTime
f = Float
+
class MultipleNamespaceService(Service):
@rpc(TypeNS1, TypeNS2)
def a(ctx, t1, t2):
return "OK"
+
class TestService(Service):
@rpc(String, _returns=String)
def aa(ctx, s):
@@ -121,98 +120,108 @@ def d(ctx, Person):
def e(ctx, Person):
pass
- @rpc(String, String, String, _returns=String,
- _in_variable_names={'_from': 'from', '_self': 'self',
- '_import': 'import'},
- _out_variable_name="return")
+ @rpc(
+ String,
+ String,
+ String,
+ _returns=String,
+ _in_variable_names={"_from": "from", "_self": "self", "_import": "import"},
+ _out_variable_name="return",
+ )
def f(ctx, _from, _self, _import):
- return '1234'
+ return "1234"
class MultipleReturnService(Service):
@rpc(String, _returns=(String, String, String))
def multi(ctx, s):
- return s, 'a', 'b'
+ return s, "a", "b"
class TestSingle(unittest.TestCase):
def setUp(self):
- self.app = Application([TestService], 'tns',
- in_protocol=Soap11(), out_protocol=Soap11())
- self.app.transport = 'null.spyne'
+ self.app = Application(
+ [TestService], "tns", in_protocol=Soap11(), out_protocol=Soap11()
+ )
+ self.app.transport = "null.spyne"
self.srv = TestService()
wsdl = Wsdl11(self.app.interface)
- wsdl.build_interface_document('URL')
+ wsdl.build_interface_document("URL")
self.wsdl_str = wsdl.get_interface_document()
self.wsdl_doc = etree.fromstring(self.wsdl_str)
def test_portypes(self):
- porttype = self.wsdl_doc.find('{http://schemas.xmlsoap.org/wsdl/}portType')
- self.assertEqual(
- len(self.srv.public_methods), len(porttype.getchildren()))
+ porttype = self.wsdl_doc.find("{http://schemas.xmlsoap.org/wsdl/}portType")
+ self.assertEqual(len(self.srv.public_methods), len(porttype.getchildren()))
def test_override_param_names(self):
- for n in [b'self', b'import', b'return', b'from']:
+ for n in [b"self", b"import", b"return", b"from"]:
assert n in self.wsdl_str, '"%s" not in self.wsdl_str'
+
class TestReturn(unittest.TestCase):
def setUp(self):
- self.app = Application([MultipleReturnService], 'tns', in_protocol=Soap11(), out_protocol=Soap11())
- self.app.transport = 'none'
+ self.app = Application(
+ [MultipleReturnService], "tns", in_protocol=Soap11(), out_protocol=Soap11()
+ )
+ self.app.transport = "none"
self.wsdl = Wsdl11(self.app.interface)
- self.wsdl.build_interface_document('URL')
+ self.wsdl.build_interface_document("URL")
def test_multiple_return(self):
- message_class = list(MultipleReturnService.public_methods.values())[0].out_message
+ message_class = list(MultipleReturnService.public_methods.values())[
+ 0
+ ].out_message
message = message_class()
self.assertEqual(len(message._type_info), 3)
- sent_xml = etree.Element('test')
- self.app.out_protocol.to_parent(None, message_class, ('a', 'b', 'c'),
- sent_xml, self.app.tns)
+ sent_xml = etree.Element("test")
+ self.app.out_protocol.to_parent(
+ None, message_class, ("a", "b", "c"), sent_xml, self.app.tns
+ )
sent_xml = sent_xml[0]
print((etree.tostring(sent_xml, pretty_print=True)))
- response_data = self.app.out_protocol.from_element(None, message_class, sent_xml)
+ response_data = self.app.out_protocol.from_element(
+ None, message_class, sent_xml
+ )
self.assertEqual(len(response_data), 3)
- self.assertEqual(response_data[0], 'a')
- self.assertEqual(response_data[1], 'b')
- self.assertEqual(response_data[2], 'c')
+ self.assertEqual(response_data[0], "a")
+ self.assertEqual(response_data[1], "b")
+ self.assertEqual(response_data[2], "c")
class TestSoap11(unittest.TestCase):
def test_simple_message(self):
m = ComplexModel.produce(
- namespace=None,
- type_name='myMessage',
- members={'s': String, 'i': Integer}
+ namespace=None, type_name="myMessage", members={"s": String, "i": Integer}
)
- m.resolve_namespace(m, 'test')
+ m.resolve_namespace(m, "test")
m_inst = m(s="a", i=43)
- e = etree.Element('test')
+ e = etree.Element("test")
Soap11().to_parent(None, m, m_inst, e, m.get_namespace())
- e=e[0]
+ e = e[0]
- self.assertEqual(e.tag, '{%s}myMessage' % m.get_namespace())
+ self.assertEqual(e.tag, "{%s}myMessage" % m.get_namespace())
- self.assertEqual(e.find('{%s}s' % m.get_namespace()).text, 'a')
- self.assertEqual(e.find('{%s}i' % m.get_namespace()).text, '43')
+ self.assertEqual(e.find("{%s}s" % m.get_namespace()).text, "a")
+ self.assertEqual(e.find("{%s}i" % m.get_namespace()).text, "43")
values = Soap11().from_element(None, m, e)
- self.assertEqual('a', values.s)
+ self.assertEqual("a", values.s)
self.assertEqual(43, values.i)
def test_href(self):
# the template. Start at pos 0, some servers complain if
# xml tag is not in the first line.
envelope_string = [
-b'''user2
-''']
+"""
+ ]
- root, xmlids = _parse_xml_string(envelope_string,
- etree.XMLParser(), 'utf8')
+ root, xmlids = _parse_xml_string(envelope_string, etree.XMLParser(), "utf8")
header, payload = _from_soap(root, xmlids)
# quick and dirty test href reconstruction
@@ -247,44 +256,44 @@ def test_href(self):
def test_namespaces(self):
m = ComplexModel.produce(
namespace="some_namespace",
- type_name='myMessage',
- members={'s': String, 'i': Integer},
+ type_name="myMessage",
+ members={"s": String, "i": Integer},
)
mi = m()
- mi.s = 'a'
+ mi.s = "a"
- e = etree.Element('test')
+ e = etree.Element("test")
Soap11().to_parent(None, m, mi, e, m.get_namespace())
- e=e[0]
+ e = e[0]
- self.assertEqual(e.tag, '{some_namespace}myMessage')
+ self.assertEqual(e.tag, "{some_namespace}myMessage")
def test_class_to_parent(self):
m = ComplexModel.produce(
- namespace=None,
- type_name='myMessage',
- members={'p': Person}
+ namespace=None, type_name="myMessage", members={"p": Person}
)
m.resolve_namespace(m, "punk")
m_inst = m()
m_inst.p = Person()
- m_inst.p.name = 'steve-o'
+ m_inst.p.name = "steve-o"
m_inst.p.age = 2
m_inst.p.addresses = []
- element=etree.Element('test')
+ element = etree.Element("test")
Soap11().to_parent(None, m, m_inst, element, m.get_namespace())
- element=element[0]
+ element = element[0]
- self.assertEqual(element.tag, '{%s}myMessage' % m.get_namespace())
- self.assertEqual(element[0].find('{%s}name' % Person.get_namespace()).text,
- 'steve-o')
- self.assertEqual(element[0].find('{%s}age' % Person.get_namespace()).text, '2')
+ self.assertEqual(element.tag, "{%s}myMessage" % m.get_namespace())
self.assertEqual(
- len(element[0].find('{%s}addresses' % Person.get_namespace())), 0)
+ element[0].find("{%s}name" % Person.get_namespace()).text, "steve-o"
+ )
+ self.assertEqual(element[0].find("{%s}age" % Person.get_namespace()).text, "2")
+ self.assertEqual(
+ len(element[0].find("{%s}addresses" % Person.get_namespace())), 0
+ )
p1 = Soap11().from_element(None, m, element)[0]
@@ -297,16 +306,22 @@ def test_datetime_fixed_format(self):
n = datetime.datetime.now(pytz.utc).replace(microsecond=0)
format = "%Y %m %d %H %M %S"
- element = etree.Element('test')
- Soap11().to_parent(None, DateTime(dt_format=format), n,
- element, 'some_namespace')
+ element = etree.Element("test")
+ Soap11().to_parent(
+ None, DateTime(dt_format=format), n, element, "some_namespace"
+ )
assert element[0].text == n.isoformat()
dt = Soap11().from_element(None, DateTime(dt_format=format), element[0])
assert n == dt
def test_date_with_tzoffset(self):
- for iso_d in ('2013-04-05', '2013-04-05+02:00', '2013-04-05-02:00', '2013-04-05Z'):
+ for iso_d in (
+ "2013-04-05",
+ "2013-04-05+02:00",
+ "2013-04-05-02:00",
+ "2013-04-05Z",
+ ):
d = Soap11().from_unicode(Date, iso_d)
assert isinstance(d, datetime.date) == True
assert d.year == 2013
@@ -315,38 +330,37 @@ def test_date_with_tzoffset(self):
def test_to_parent_nested(self):
m = ComplexModel.produce(
- namespace=None,
- type_name='myMessage',
- members={'p':Person}
+ namespace=None, type_name="myMessage", members={"p": Person}
)
m.resolve_namespace(m, "m")
p = Person()
- p.name = 'steve-o'
+ p.name = "steve-o"
p.age = 2
p.addresses = []
for i in range(0, 100):
a = Address()
- a.street = '123 happy way'
+ a.street = "123 happy way"
a.zip = i
- a.laditude = '45.22'
- a.longitude = '444.234'
+ a.laditude = "45.22"
+ a.longitude = "444.234"
p.addresses.append(a)
m_inst = m(p=p)
- element=etree.Element('test')
+ element = etree.Element("test")
Soap11().to_parent(None, m, m_inst, element, m.get_namespace())
- element=element[0]
+ element = element[0]
- self.assertEqual('{%s}myMessage' % m.get_namespace(), element.tag)
+ self.assertEqual("{%s}myMessage" % m.get_namespace(), element.tag)
- addresses = element[0].find('{%s}addresses' % Person.get_namespace())
+ addresses = element[0].find("{%s}addresses" % Person.get_namespace())
self.assertEqual(100, len(addresses))
- self.assertEqual('0', addresses[0].find('{%s}zip' %
- Address.get_namespace()).text)
+ self.assertEqual(
+ "0", addresses[0].find("{%s}zip" % Address.get_namespace()).text
+ )
def test_fault_deserialization_missing_fault_actor(self):
element = etree.fromstring(b"""
@@ -371,45 +385,47 @@ def test_fault_deserialization_missing_fault_actor(self):
# TestSoapHeader supporting classes.
# SOAP Header Elements defined by WS-Addressing.
-NAMESPACE_ADDRESSING = 'http://www.w3.org/2005/08/addressing'
+NAMESPACE_ADDRESSING = "http://www.w3.org/2005/08/addressing"
+
-class Action (Unicode):
+class Action(Unicode):
__type_name__ = "Action"
__namespace__ = NAMESPACE_ADDRESSING
-class MessageID (Unicode):
+
+class MessageID(Unicode):
__type_name__ = "MessageID"
__namespace__ = NAMESPACE_ADDRESSING
-class RelatesTo (Unicode):
+
+class RelatesTo(Unicode):
__type_name__ = "RelatesTo"
__namespace__ = NAMESPACE_ADDRESSING
+
class SOAPServiceWithHeader(Service):
- @rpc(Unicode,
- _in_header=(Action,
- MessageID,
- RelatesTo),
- _out_variable_name= 'status',
- _returns=Unicode
- )
+ @rpc(
+ Unicode,
+ _in_header=(Action, MessageID, RelatesTo),
+ _out_variable_name="status",
+ _returns=Unicode,
+ )
def someRequest(ctx, response):
- print (response)
- return 'OK'
+ print(response)
+ return "OK"
+
class TestSoapHeader(unittest.TestCase):
def setUp(self):
- self.app = Application([SOAPServiceWithHeader],
- 'tns',
- in_protocol=Soap11(),
- out_protocol=Soap11())
+ self.app = Application(
+ [SOAPServiceWithHeader], "tns", in_protocol=Soap11(), out_protocol=Soap11()
+ )
def test_soap_input_header(self):
server = ServerBase(self.app)
initial_ctx = MethodContext(server, MethodContext.SERVER)
- initial_ctx.in_string = [
- b'''
@@ -422,15 +438,14 @@ def test_soap_input_header(self):
OK
- '''
- ]
+ """]
- ctx, = server.generate_contexts(initial_ctx, in_string_charset='utf8')
+ (ctx,) = server.generate_contexts(initial_ctx, in_string_charset="utf8")
server.get_in_object(ctx)
- self.assertEqual(ctx.in_header[0], '/SomeAction')
- self.assertEqual(ctx.in_header[1], 'SomeMessageID')
- self.assertEqual(ctx.in_header[2], 'SomeRelatesToID')
+ self.assertEqual(ctx.in_header[0], "/SomeAction")
+ self.assertEqual(ctx.in_header[1], "SomeMessageID")
+ self.assertEqual(ctx.in_header[2], "SomeRelatesToID")
def test_soap_input_header_order(self):
"""
@@ -439,8 +454,7 @@ def test_soap_input_header_order(self):
"""
server = ServerBase(self.app)
initial_ctx = MethodContext(server, MethodContext.SERVER)
- initial_ctx.in_string = [
- b'''
@@ -453,16 +467,14 @@ def test_soap_input_header_order(self):
OK
- '''
- ]
+ """]
- ctx, = server.generate_contexts(initial_ctx, in_string_charset='utf8')
+ (ctx,) = server.generate_contexts(initial_ctx, in_string_charset="utf8")
server.get_in_object(ctx)
- self.assertEqual(ctx.in_header[0], '/SomeAction')
- self.assertEqual(ctx.in_header[1], 'SomeMessageID')
- self.assertEqual(ctx.in_header[2], 'SomeRelatesToID')
-
+ self.assertEqual(ctx.in_header[0], "/SomeAction")
+ self.assertEqual(ctx.in_header[1], "SomeMessageID")
+ self.assertEqual(ctx.in_header[2], "SomeRelatesToID")
def test_soap_input_header_order_and_missing(self):
"""
@@ -472,8 +484,7 @@ def test_soap_input_header_order_and_missing(self):
"""
server = ServerBase(self.app)
initial_ctx = MethodContext(server, MethodContext.SERVER)
- initial_ctx.in_string = [
- b'''
@@ -485,16 +496,15 @@ def test_soap_input_header_order_and_missing(self):
OK
- '''
- ]
+ """]
- ctx, = server.generate_contexts(initial_ctx, in_string_charset='utf8')
+ (ctx,) = server.generate_contexts(initial_ctx, in_string_charset="utf8")
server.get_in_object(ctx)
- self.assertEqual(ctx.in_header[0], '/SomeAction')
- self.assertEqual(ctx.in_header[1], 'SomeMessageID')
+ self.assertEqual(ctx.in_header[0], "/SomeAction")
+ self.assertEqual(ctx.in_header[1], "SomeMessageID")
self.assertEqual(ctx.in_header[2], None)
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/protocol/test_soap12.py b/spyne/test/protocol/test_soap12.py
index 9fc20656a..7e451bcc2 100755
--- a/spyne/test/protocol/test_soap12.py
+++ b/spyne/test/protocol/test_soap12.py
@@ -3,15 +3,16 @@
from __future__ import unicode_literals
import unittest
+from io import BytesIO
from lxml import etree
-from lxml.doctestcompare import LXMLOutputChecker, PARSE_XML
+from lxml.doctestcompare import PARSE_XML, LXMLOutputChecker
-from spyne import Fault, Unicode, ByteArray
+from spyne import ByteArray, Fault, Unicode
from spyne.application import Application
from spyne.const import xml as ns
from spyne.const.xml import NS_SOAP11_ENV
-from spyne.decorator import srpc, rpc
+from spyne.decorator import rpc, srpc
from spyne.interface import Wsdl11
from spyne.model.complex import ComplexModel
from spyne.model.primitive import Integer, String
@@ -20,9 +21,12 @@
from spyne.protocol.xml import XmlDocument
from spyne.server.wsgi import WsgiApplication
from spyne.service import Service
-from spyne.test.protocol.test_soap11 import TestService, TestSingle, \
- TestReturn, MultipleReturnService
-from spyne.util.six import BytesIO
+from spyne.test.protocol.test_soap11 import (
+ MultipleReturnService,
+ TestReturn,
+ TestService,
+ TestSingle,
+)
def start_response(code, headers):
@@ -67,22 +71,26 @@ class DownloadPartFileResult(ComplexModel):
class TestSingleSoap12(TestSingle):
def setUp(self):
- self.app = Application([TestService], 'tns', in_protocol=Soap12(), out_protocol=Soap12())
- self.app.transport = 'null.spyne'
+ self.app = Application(
+ [TestService], "tns", in_protocol=Soap12(), out_protocol=Soap12()
+ )
+ self.app.transport = "null.spyne"
self.srv = TestService()
wsdl = Wsdl11(self.app.interface)
- wsdl.build_interface_document('URL')
+ wsdl.build_interface_document("URL")
self.wsdl_str = wsdl.get_interface_document()
self.wsdl_doc = etree.fromstring(self.wsdl_str)
class TestMultipleSoap12(TestReturn):
def setUp(self):
- self.app = Application([MultipleReturnService], 'tns', in_protocol=Soap12(), out_protocol=Soap12())
- self.app.transport = 'none'
+ self.app = Application(
+ [MultipleReturnService], "tns", in_protocol=Soap12(), out_protocol=Soap12()
+ )
+ self.app.transport = "none"
self.wsdl = Wsdl11(self.app.interface)
- self.wsdl.build_interface_document('URL')
+ self.wsdl.build_interface_document("URL")
class TestSoap12(unittest.TestCase):
@@ -116,9 +124,15 @@ class SoapException(Service):
@srpc()
def soap_exception():
raise Fault(
- "Client.Plausible.issue", "A plausible fault", 'http://faultactor.example.com',
- detail={'some':'extra info'})
- app = Application([SoapException], 'tns', in_protocol=Soap12(), out_protocol=Soap12())
+ "Client.Plausible.issue",
+ "A plausible fault",
+ "http://faultactor.example.com",
+ detail={"some": "extra info"},
+ )
+
+ app = Application(
+ [SoapException], "tns", in_protocol=Soap12(), out_protocol=Soap12()
+ )
req = b"""
"; '
- 'start-info="application/soap+xml"; action="sendDocument"',
- 'wsgi.input': BytesIO(MTOM_REQUEST.replace(b"\n", b"\r\n"))
- }, start_response, "http://null")))
+ response = etree.fromstring(
+ b"".join(
+ server(
+ {
+ "QUERY_STRING": "",
+ "PATH_INFO": "/call",
+ "REQUEST_METHOD": "POST",
+ "CONTENT_TYPE": "Content-Type: multipart/related; "
+ 'type="application/xop+xml"; '
+ 'boundary="uuid:2e53e161-b47f-444a-b594-eb6b72e76997"; '
+ 'start=""; '
+ 'start-info="application/soap+xml"; action="sendDocument"',
+ "wsgi.input": BytesIO(MTOM_REQUEST.replace(b"\n", b"\r\n")),
+ },
+ start_response,
+ "http://null",
+ )
+ )
+ )
response_str = etree.tostring(response, pretty_print=True)
print(response_str)
nsdict = dict(tns=TNS)
- assert etree.fromstring(response_str) \
- .xpath(".//tns:documentRequestResult/text()", namespaces=nsdict) \
- == [FILE_NAME]
+ assert etree.fromstring(response_str).xpath(
+ ".//tns:documentRequestResult/text()", namespaces=nsdict
+ ) == [FILE_NAME]
def test_mtom_join_envelope_chunks(self):
- FILE_NAME = 'EA055406-5881-4F02-A3DC-9A5A7510D018.dat'
- TNS = 'http://gib.gov.tr/vedop3/eFatura'
+ FILE_NAME = "EA055406-5881-4F02-A3DC-9A5A7510D018.dat"
+ TNS = "http://gib.gov.tr/vedop3/eFatura"
# large enough payload to be chunked
PAYLOAD = b"sample data " * 1024
+
class SomeService(Service):
- @rpc(Unicode(sub_name="fileName"), ByteArray(sub_name='binaryData'),
- ByteArray(sub_name="hash"), _returns=Unicode)
+ @rpc(
+ Unicode(sub_name="fileName"),
+ ByteArray(sub_name="binaryData"),
+ ByteArray(sub_name="hash"),
+ _returns=Unicode,
+ )
def documentRequest(ctx, file_name, file_data, data_hash):
assert file_name == FILE_NAME
assert file_data == (PAYLOAD,)
return file_name
- app = Application([SomeService], tns=TNS,
- in_protocol=Soap12(), out_protocol=Soap12())
+ app = Application(
+ [SomeService], tns=TNS, in_protocol=Soap12(), out_protocol=Soap12()
+ )
server = WsgiApplication(app, block_length=1024)
- response = etree.fromstring(b''.join(server({
- 'QUERY_STRING': '',
- 'PATH_INFO': '/call',
- 'REQUEST_METHOD': 'POST',
- 'CONTENT_TYPE': 'Content-Type: multipart/related; '
- 'type="application/xop+xml"; '
- 'boundary="uuid:2e53e161-b47f-444a-b594-eb6b72e76997"; '
- 'start=""; '
- 'start-info="application/soap+xml"; action="sendDocument"',
- 'wsgi.input': BytesIO(MTOM_REQUEST
- .replace(b"\n", b"\r\n")
- .replace(b"sample data", PAYLOAD)),
- }, start_response, "http://null")))
+ response = etree.fromstring(
+ b"".join(
+ server(
+ {
+ "QUERY_STRING": "",
+ "PATH_INFO": "/call",
+ "REQUEST_METHOD": "POST",
+ "CONTENT_TYPE": "Content-Type: multipart/related; "
+ 'type="application/xop+xml"; '
+ 'boundary="uuid:2e53e161-b47f-444a-b594-eb6b72e76997"; '
+ 'start=""; '
+ 'start-info="application/soap+xml"; action="sendDocument"',
+ "wsgi.input": BytesIO(
+ MTOM_REQUEST.replace(b"\n", b"\r\n").replace(
+ b"sample data", PAYLOAD
+ )
+ ),
+ },
+ start_response,
+ "http://null",
+ )
+ )
+ )
response_str = etree.tostring(response, pretty_print=True)
print(response_str)
nsdict = dict(tns=TNS)
- assert etree.fromstring(response_str) \
- .xpath(".//tns:documentRequestResult/text()", namespaces=nsdict) \
- == [FILE_NAME]
+ assert etree.fromstring(response_str).xpath(
+ ".//tns:documentRequestResult/text()", namespaces=nsdict
+ ) == [FILE_NAME]
def test_bytes_join_attachment(self):
href_id = "http://tempuri.org/1/634133419330914808"
payload = "ANJNSLJNDYBC SFDJNIREMX:CMKSAJN"
- envelope = '''
+ envelope = """
@@ -278,10 +330,11 @@ def test_bytes_join_attachment(self):
- ''' % href_id
+ """ % href_id
- (joinedmsg, numreplaces) = _join_attachment(NS_SOAP11_ENV,
- href_id, envelope, payload)
+ joinedmsg, numreplaces = _join_attachment(
+ NS_SOAP11_ENV, href_id, envelope, payload
+ )
soaptree = etree.fromstring(joinedmsg)
@@ -293,5 +346,5 @@ def test_bytes_join_attachment(self):
self.assertEqual(payload, r.Data)
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/protocol/test_xml.py b/spyne/test/protocol/test_xml.py
index fc3cb0ee3..035afe68b 100755
--- a/spyne/test/protocol/test_xml.py
+++ b/spyne/test/protocol/test_xml.py
@@ -21,36 +21,39 @@
from __future__ import print_function
import logging
+
logging.basicConfig(level=logging.DEBUG)
+import datetime
+import decimal
import sys
import unittest
-import decimal
-import datetime
-
-from pprint import pprint
from base64 import b64encode
+from io import BytesIO
+from pprint import pprint
from lxml import etree
from lxml.builder import E
-from spyne import MethodContext, rpc, ByteArray, File, AnyXml, Ignored
-from spyne.context import FakeContext
-from spyne.const import RESULT_SUFFIX
-from spyne.service import Service
-from spyne.server import ServerBase
+from spyne import AnyXml, ByteArray, File, Ignored, MethodContext, rpc
from spyne.application import Application
+from spyne.const import RESULT_SUFFIX
+from spyne.const.xml import NS_XSI
+from spyne.context import FakeContext
from spyne.decorator import srpc
-from spyne.util.six import BytesIO
-from spyne.model import Fault, Integer, Decimal, Unicode, Date, DateTime, \
- XmlData, Array, ComplexModel, XmlAttribute, Mandatory as M
-from spyne.protocol.xml import XmlDocument, SchemaValidationError
-
-from spyne.util import six
-from spyne.util.xml import get_xml_as_object, get_object_as_xml, \
- get_object_as_xml_polymorphic, get_xml_as_object_polymorphic
+from spyne.model import Array, ComplexModel, Date, DateTime, Decimal, Fault, Integer
+from spyne.model import Mandatory as M
+from spyne.model import Unicode, XmlAttribute, XmlData
+from spyne.protocol.xml import SchemaValidationError, XmlDocument
+from spyne.server import ServerBase
from spyne.server.wsgi import WsgiApplication
-from spyne.const.xml import NS_XSI
+from spyne.service import Service
+from spyne.util.xml import (
+ get_object_as_xml,
+ get_object_as_xml_polymorphic,
+ get_xml_as_object,
+ get_xml_as_object_polymorphic,
+)
class TestXml(unittest.TestCase):
@@ -58,16 +61,16 @@ def test_empty_string(self):
class a(ComplexModel):
b = Unicode
- elt = etree.fromstring('')
+ elt = etree.fromstring("")
o = get_xml_as_object(elt, a)
- assert o.b == ''
+ assert o.b == ""
def test_ignored(self):
- d = decimal.Decimal('1e100')
+ d = decimal.Decimal("1e100")
class SomeService(Service):
- @srpc(Decimal(120,4), _returns=Decimal)
+ @srpc(Decimal(120, 4), _returns=Decimal)
def some_call(p):
print(p)
print(type(p))
@@ -75,27 +78,27 @@ def some_call(p):
assert d == p
return Ignored(p)
- app = Application([SomeService], "tns", in_protocol=XmlDocument(),
- out_protocol=XmlDocument())
+ app = Application(
+ [SomeService], "tns", in_protocol=XmlDocument(), out_protocol=XmlDocument()
+ )
server = ServerBase(app)
initial_ctx = MethodContext(server, MethodContext.SERVER)
initial_ctx.in_string = [
b'',
- str(d).encode('ascii'),
- b'
'
+ str(d).encode("ascii"),
+ b"
",
]
- ctx, = server.generate_contexts(initial_ctx)
+ (ctx,) = server.generate_contexts(initial_ctx)
server.get_in_object(ctx)
server.get_out_object(ctx)
server.get_out_string(ctx)
- elt = etree.fromstring(b''.join(ctx.out_string))
+ elt = etree.fromstring(b"".join(ctx.out_string))
- logging.info(etree.tostring(elt, pretty_print=True).decode('utf8'))
+ logging.info(etree.tostring(elt, pretty_print=True).decode("utf8"))
assert 0 == len(list(elt))
-
def test_xml_data(self):
class C(ComplexModel):
a = XmlData(Unicode)
@@ -104,21 +107,24 @@ class C(ComplexModel):
class SomeService(Service):
@srpc(C, _returns=C)
def some_call(c):
- assert c.a == 'a'
- assert c.b == 'b'
+ assert c.a == "a"
+ assert c.b == "b"
return c
- app = Application([SomeService], "tns", name="test_xml_data",
- in_protocol=XmlDocument(), out_protocol=XmlDocument())
+ app = Application(
+ [SomeService],
+ "tns",
+ name="test_xml_data",
+ in_protocol=XmlDocument(),
+ out_protocol=XmlDocument(),
+ )
server = ServerBase(app)
initial_ctx = MethodContext(server, MethodContext.SERVER)
initial_ctx.in_string = [
- b''
- b'a'
- b''
+ b'' b'a' b""
]
- ctx, = server.generate_contexts(initial_ctx)
+ (ctx,) = server.generate_contexts(initial_ctx)
server.get_in_object(ctx)
server.get_out_object(ctx)
server.get_out_string(ctx)
@@ -126,41 +132,42 @@ def some_call(c):
print(ctx.out_string)
pprint(app.interface.nsmap)
- ret = etree.fromstring(b''.join(ctx.out_string)).xpath(
- '//tns:some_call' + RESULT_SUFFIX, namespaces=app.interface.nsmap)[0]
+ ret = etree.fromstring(b"".join(ctx.out_string)).xpath(
+ "//tns:some_call" + RESULT_SUFFIX, namespaces=app.interface.nsmap
+ )[0]
print(etree.tostring(ret, pretty_print=True))
assert ret.text == "a"
- assert ret.attrib['b'] == "b"
+ assert ret.attrib["b"] == "b"
def test_wrapped_array(self):
- parent = etree.Element('parent')
- val = ['a', 'b']
- cls = Array(Unicode, namespace='tns')
- XmlDocument().to_parent(None, cls, val, parent, 'tns')
+ parent = etree.Element("parent")
+ val = ["a", "b"]
+ cls = Array(Unicode, namespace="tns")
+ XmlDocument().to_parent(None, cls, val, parent, "tns")
print(etree.tostring(parent, pretty_print=True))
- xpath = parent.xpath('//x:stringArray/x:string/text()',
- namespaces={'x': 'tns'})
+ xpath = parent.xpath("//x:stringArray/x:string/text()", namespaces={"x": "tns"})
assert xpath == val
def test_simple_array(self):
class cls(ComplexModel):
- __namespace__ = 'tns'
- s = Unicode(max_occurs='unbounded')
- val = cls(s=['a', 'b'])
+ __namespace__ = "tns"
+ s = Unicode(max_occurs="unbounded")
+
+ val = cls(s=["a", "b"])
- parent = etree.Element('parent')
- XmlDocument().to_parent(None, cls, val, parent, 'tns')
+ parent = etree.Element("parent")
+ XmlDocument().to_parent(None, cls, val, parent, "tns")
print(etree.tostring(parent, pretty_print=True))
- xpath = parent.xpath('//x:cls/x:s/text()', namespaces={'x': 'tns'})
+ xpath = parent.xpath("//x:cls/x:s/text()", namespaces={"x": "tns"})
assert xpath == val.s
def test_decimal(self):
- d = decimal.Decimal('1e100')
+ d = decimal.Decimal("1e100")
class SomeService(Service):
- @srpc(Decimal(120,4), _returns=Decimal)
+ @srpc(Decimal(120, 4), _returns=Decimal)
def some_call(p):
print(p)
print(type(p))
@@ -168,32 +175,34 @@ def some_call(p):
assert d == p
return p
- app = Application([SomeService], "tns", in_protocol=XmlDocument(),
- out_protocol=XmlDocument())
+ app = Application(
+ [SomeService], "tns", in_protocol=XmlDocument(), out_protocol=XmlDocument()
+ )
server = ServerBase(app)
initial_ctx = MethodContext(server, MethodContext.SERVER)
initial_ctx.in_string = [
b'',
- str(d).encode('ascii'),
- b'
'
+ str(d).encode("ascii"),
+ b"",
]
- ctx, = server.generate_contexts(initial_ctx)
+ (ctx,) = server.generate_contexts(initial_ctx)
server.get_in_object(ctx)
server.get_out_object(ctx)
server.get_out_string(ctx)
- elt = etree.fromstring(b''.join(ctx.out_string))
+ elt = etree.fromstring(b"".join(ctx.out_string))
print(etree.tostring(elt, pretty_print=True))
- target = elt.xpath('//tns:some_callResult/text()',
- namespaces=app.interface.nsmap)[0]
+ target = elt.xpath(
+ "//tns:some_callResult/text()", namespaces=app.interface.nsmap
+ )[0]
assert target == str(d)
def test_subs(self):
from lxml import etree
- from spyne.util.xml import get_xml_as_object
- from spyne.util.xml import get_object_as_xml
+
+ from spyne.util.xml import get_object_as_xml, get_xml_as_object
m = {
"s0": "aa",
@@ -211,9 +220,9 @@ class C(ComplexModel):
elt = get_object_as_xml(C(a=1, b=2, c=3, d=4), C)
print(etree.tostring(elt, pretty_print=True))
- assert elt.xpath("s0:a/text()", namespaces=m) == ["1"]
+ assert elt.xpath("s0:a/text()", namespaces=m) == ["1"]
assert elt.xpath("s0:bb/text()", namespaces=m) == ["2"]
- assert elt.xpath("s2:c/text()", namespaces=m) == ["3"]
+ assert elt.xpath("s2:c/text()", namespaces=m) == ["3"]
assert elt.xpath("s3:dd/text()", namespaces=m) == ["4"]
c = get_xml_as_object(elt, C)
@@ -225,8 +234,8 @@ class C(ComplexModel):
def test_sub_attributes(self):
from lxml import etree
- from spyne.util.xml import get_xml_as_object
- from spyne.util.xml import get_object_as_xml
+
+ from spyne.util.xml import get_object_as_xml, get_xml_as_object
m = {
"s0": "aa",
@@ -244,9 +253,9 @@ class C(ComplexModel):
elt = get_object_as_xml(C(a=1, b=2, c=3, d=4), C)
print(etree.tostring(elt, pretty_print=True))
- assert elt.xpath("//*/@a") == ["1"]
+ assert elt.xpath("//*/@a") == ["1"]
assert elt.xpath("//*/@bb") == ["2"]
- assert elt.xpath("//*/@s2:c", namespaces=m) == ["3"]
+ assert elt.xpath("//*/@s2:c", namespaces=m) == ["3"]
assert elt.xpath("//*/@s3:dd", namespaces=m) == ["4"]
c = get_xml_as_object(elt, C)
@@ -259,10 +268,10 @@ class C(ComplexModel):
def test_dates(self):
d = Date
xml_dates = [
- etree.fromstring(b'2013-04-05'),
- etree.fromstring(b'2013-04-05+02:00'),
- etree.fromstring(b'2013-04-05-02:00'),
- etree.fromstring(b'2013-04-05Z'),
+ etree.fromstring(b"2013-04-05"),
+ etree.fromstring(b"2013-04-05+02:00"),
+ etree.fromstring(b"2013-04-05-02:00"),
+ etree.fromstring(b"2013-04-05Z"),
]
for xml_date in xml_dates:
@@ -274,29 +283,26 @@ def test_dates(self):
def test_datetime_usec(self):
fs = etree.fromstring
- d = get_xml_as_object(fs('2013-04-05T06:07:08.123456'), DateTime)
+ d = get_xml_as_object(fs("2013-04-05T06:07:08.123456"), DateTime)
assert d.microsecond == 123456
# rounds up
- d = get_xml_as_object(fs('2013-04-05T06:07:08.1234567'), DateTime)
+ d = get_xml_as_object(fs("2013-04-05T06:07:08.1234567"), DateTime)
assert d.microsecond == 123457
# rounds down
- d = get_xml_as_object(fs('2013-04-05T06:07:08.1234564'), DateTime)
+ d = get_xml_as_object(fs("2013-04-05T06:07:08.1234564"), DateTime)
assert d.microsecond == 123456
# rounds up as well
- d = get_xml_as_object(fs('2013-04-05T06:07:08.1234565'), DateTime)
+ d = get_xml_as_object(fs("2013-04-05T06:07:08.1234565"), DateTime)
# FIXME: this is very interesting. why?
- if not six.PY2:
- assert d.microsecond == 123456
- else:
- assert d.microsecond == 123457
+ assert d.microsecond == 123456
def _get_ctx(self, server, in_string):
initial_ctx = MethodContext(server, MethodContext.SERVER)
initial_ctx.in_string = in_string
- ctx, = server.generate_contexts(initial_ctx)
+ (ctx,) = server.generate_contexts(initial_ctx)
server.get_in_object(ctx)
return ctx
@@ -304,65 +310,73 @@ def test_mandatory_elements(self):
class SomeService(Service):
@srpc(M(Unicode), _returns=Unicode)
def some_call(s):
- assert s == 'hello'
+ assert s == "hello"
return s
- app = Application([SomeService], "tns", name="test_mandatory_elements",
- in_protocol=XmlDocument(validator='lxml'),
- out_protocol=XmlDocument())
+ app = Application(
+ [SomeService],
+ "tns",
+ name="test_mandatory_elements",
+ in_protocol=XmlDocument(validator="lxml"),
+ out_protocol=XmlDocument(),
+ )
server = ServerBase(app)
# Valid call with all mandatory elements in
- ctx = self._get_ctx(server, [
- b''
- b'hello'
- b''
- ])
+ ctx = self._get_ctx(
+ server, [b'' b"hello" b""]
+ )
server.get_out_object(ctx)
server.get_out_string(ctx)
- ret = etree.fromstring(b''.join(ctx.out_string)).xpath(
- '//tns:some_call%s/text()' % RESULT_SUFFIX,
- namespaces=app.interface.nsmap)[0]
- assert ret == 'hello'
+ ret = etree.fromstring(b"".join(ctx.out_string)).xpath(
+ "//tns:some_call%s/text()" % RESULT_SUFFIX, namespaces=app.interface.nsmap
+ )[0]
+ assert ret == "hello"
# Invalid call
- ctx = self._get_ctx(server, [
- b''
+ ctx = self._get_ctx(
+ server,
+ [
+ b''
# no mandatory elements here...
- b''
- ])
+ b""
+ ],
+ )
self.assertRaises(SchemaValidationError, server.get_out_object, ctx)
def test_unicode_chars_in_exception(self):
class SomeService(Service):
- @srpc(Unicode(pattern=u'x'), _returns=Unicode)
+ @srpc(Unicode(pattern="x"), _returns=Unicode)
def some_call(s):
test(should, never, reach, here)
- app = Application([SomeService], "tns", name="test_mandatory_elements",
- in_protocol=XmlDocument(validator='lxml'),
- out_protocol=XmlDocument())
+ app = Application(
+ [SomeService],
+ "tns",
+ name="test_mandatory_elements",
+ in_protocol=XmlDocument(validator="lxml"),
+ out_protocol=XmlDocument(),
+ )
server = WsgiApplication(app)
- req = (
- u''
- u'Ğ'
- u''
- ).encode('utf8')
+ req = ('' "Ğ" "").encode("utf8")
print("AAA")
- resp = server({
- 'QUERY_STRING': '',
- 'PATH_INFO': '/',
- 'REQUEST_METHOD': 'POST',
- 'SERVER_NAME': 'localhost',
- 'SERVER_PORT': '80',
- 'wsgi.input': BytesIO(req),
- "wsgi.url_scheme": 'http',
- }, lambda x, y: print(x,y))
+ resp = server(
+ {
+ "QUERY_STRING": "",
+ "PATH_INFO": "/",
+ "REQUEST_METHOD": "POST",
+ "SERVER_NAME": "localhost",
+ "SERVER_PORT": "80",
+ "wsgi.input": BytesIO(req),
+ "wsgi.url_scheme": "http",
+ },
+ lambda x, y: print(x, y),
+ )
print("AAA")
- assert u'Ğ'.encode('utf8') in b''.join(resp)
+ assert "Ğ".encode("utf8") in b"".join(resp)
def test_mandatory_subelements(self):
class C(ComplexModel):
@@ -372,29 +386,38 @@ class SomeService(Service):
@srpc(C.customize(min_occurs=1), _returns=Unicode)
def some_call(c):
assert c is not None
- assert c.foo == 'hello'
+ assert c.foo == "hello"
return c.foo
app = Application(
- [SomeService], "tns", name="test_mandatory_subelements",
- in_protocol=XmlDocument(validator='lxml'),
- out_protocol=XmlDocument())
+ [SomeService],
+ "tns",
+ name="test_mandatory_subelements",
+ in_protocol=XmlDocument(validator="lxml"),
+ out_protocol=XmlDocument(),
+ )
server = ServerBase(app)
- ctx = self._get_ctx(server, [
- b''
+ ctx = self._get_ctx(
+ server,
+ [
+ b''
# no mandatory elements at all...
- b''
- ])
+ b""
+ ],
+ )
self.assertRaises(SchemaValidationError, server.get_out_object, ctx)
- ctx = self._get_ctx(server, [
- b''
- b''
- # no mandatory elements here...
- b''
- b''
- ])
+ ctx = self._get_ctx(
+ server,
+ [
+ b''
+ b""
+ # no mandatory elements here...
+ b""
+ b""
+ ],
+ )
self.assertRaises(SchemaValidationError, server.get_out_object, ctx)
def test_mandatory_element_attributes(self):
@@ -405,30 +428,39 @@ class SomeService(Service):
@srpc(C.customize(min_occurs=1), _returns=Unicode)
def some_call(c):
assert c is not None
- assert hasattr(c, 'foo')
- assert c.foo == 'hello'
+ assert hasattr(c, "foo")
+ assert c.foo == "hello"
return c.foo
app = Application(
- [SomeService], "tns", name="test_mandatory_element_attributes",
- in_protocol=XmlDocument(validator='lxml'),
- out_protocol=XmlDocument())
+ [SomeService],
+ "tns",
+ name="test_mandatory_element_attributes",
+ in_protocol=XmlDocument(validator="lxml"),
+ out_protocol=XmlDocument(),
+ )
server = ServerBase(app)
- ctx = self._get_ctx(server, [
- b''
+ ctx = self._get_ctx(
+ server,
+ [
+ b''
# no mandatory elements at all...
- b''
- ])
+ b""
+ ],
+ )
self.assertRaises(SchemaValidationError, server.get_out_object, ctx)
- ctx = self._get_ctx(server, [
- b''
- b''
- # no mandatory elements here...
- b''
- b''
- ])
+ ctx = self._get_ctx(
+ server,
+ [
+ b''
+ b""
+ # no mandatory elements here...
+ b""
+ b""
+ ],
+ )
self.assertRaises(SchemaValidationError, server.get_out_object, ctx)
def test_bare_sub_name_ns(self):
@@ -436,33 +468,37 @@ class Action(ComplexModel):
class Attributes(ComplexModel.Attributes):
sub_ns = "SOME_NS"
sub_name = "Action"
+
data = XmlData(Unicode)
must_understand = XmlAttribute(Unicode)
elt = get_object_as_xml(Action("x", must_understand="y"), Action)
eltstr = etree.tostring(elt)
print(eltstr)
- assert eltstr == b'x'
+ assert (
+ eltstr
+ == b'x'
+ )
def test_null_mandatory_attribute(self):
- class Action (ComplexModel):
+ class Action(ComplexModel):
data = XmlAttribute(M(Unicode))
elt = get_object_as_xml(Action(), Action)
eltstr = etree.tostring(elt)
print(eltstr)
- assert eltstr == b''
+ assert eltstr == b""
def test_bytearray(self):
- v = b'aaaa'
- elt = get_object_as_xml([v], ByteArray, 'B')
+ v = b"aaaa"
+ elt = get_object_as_xml([v], ByteArray, "B")
eltstr = etree.tostring(elt)
print(eltstr)
- assert elt.text == b64encode(v).decode('ascii')
+ assert elt.text == b64encode(v).decode("ascii")
def test_any_xml_text(self):
- v = u""
- elt = get_object_as_xml(v, AnyXml, 'B', no_namespace=True)
+ v = ""
+ elt = get_object_as_xml(v, AnyXml, "B", no_namespace=True)
eltstr = etree.tostring(elt)
print(eltstr)
assert etree.tostring(elt[0], encoding="unicode") == v
@@ -470,78 +506,81 @@ def test_any_xml_text(self):
def test_any_xml_bytes(self):
v = b""
- elt = get_object_as_xml(v, AnyXml, 'B', no_namespace=True)
+ elt = get_object_as_xml(v, AnyXml, "B", no_namespace=True)
eltstr = etree.tostring(elt)
print(eltstr)
assert etree.tostring(elt[0]) == v
def test_any_xml_elt(self):
v = E.roots(E.bloody(E.roots()))
- elt = get_object_as_xml(v, AnyXml, 'B')
+ elt = get_object_as_xml(v, AnyXml, "B")
eltstr = etree.tostring(elt)
print(eltstr)
assert etree.tostring(elt[0]) == etree.tostring(v)
def test_file(self):
- v = b'aaaa'
+ v = b"aaaa"
f = BytesIO(v)
- elt = get_object_as_xml(File.Value(handle=f), File, 'B')
+ elt = get_object_as_xml(File.Value(handle=f), File, "B")
eltstr = etree.tostring(elt)
print(eltstr)
- assert elt.text == b64encode(v).decode('ascii')
+ assert elt.text == b64encode(v).decode("ascii")
def test_fault_detail_as_dict(self):
elt = get_object_as_xml(Fault(detail={"this": "that"}), Fault)
eltstr = etree.tostring(elt)
print(eltstr)
- assert b'that' in eltstr
+ assert b"that" in eltstr
def test_xml_encoding(self):
- ctx = FakeContext(out_document=E.rain(u"yağmur"))
- XmlDocument(encoding='iso-8859-9').create_out_string(ctx)
- s = b''.join(ctx.out_string)
- assert u"ğ".encode('iso-8859-9') in s
+ ctx = FakeContext(out_document=E.rain("yağmur"))
+ XmlDocument(encoding="iso-8859-9").create_out_string(ctx)
+ s = b"".join(ctx.out_string)
+ assert "ğ".encode("iso-8859-9") in s
def test_default(self):
class SomeComplexModel(ComplexModel):
_type_info = [
- ('a', Unicode),
- ('b', Unicode(default='default')),
+ ("a", Unicode),
+ ("b", Unicode(default="default")),
]
obj = XmlDocument().from_element(
- None, SomeComplexModel,
+ None,
+ SomeComplexModel,
etree.fromstring("""
string
- """)
+ """),
)
# xml schema says it should be None
- assert obj.b == 'default'
+ assert obj.b == "default"
obj = XmlDocument().from_element(
- None, SomeComplexModel,
+ None,
+ SomeComplexModel,
etree.fromstring("""
string
- """ % NS_XSI)
+ """ % NS_XSI),
)
# xml schema says it should be 'default'
- assert obj.b == 'default'
+ assert obj.b == "default"
obj = XmlDocument(replace_null_with_default=False).from_element(
- None, SomeComplexModel,
+ None,
+ SomeComplexModel,
etree.fromstring("""
string
- """ % NS_XSI)
+ """ % NS_XSI),
)
# xml schema says it should be 'default'
@@ -550,9 +589,9 @@ class SomeComplexModel(ComplexModel):
def test_polymorphic_roundtrip(self):
class B(ComplexModel):
- __namespace__ = 'some_ns'
+ __namespace__ = "some_ns"
_type_info = {
- '_b': Unicode,
+ "_b": Unicode,
}
def __init__(self):
@@ -560,9 +599,9 @@ def __init__(self):
self._b = "b"
class C(B):
- __namespace__ = 'some_ns'
+ __namespace__ = "some_ns"
_type_info = {
- '_c': Unicode,
+ "_c": Unicode,
}
def __init__(self):
@@ -570,24 +609,21 @@ def __init__(self):
self._c = "c"
class A(ComplexModel):
- __namespace__ = 'some_ns'
+ __namespace__ = "some_ns"
_type_info = {
- '_a': Unicode,
- '_b': B,
+ "_a": Unicode,
+ "_b": B,
}
def __init__(self, b=None):
super(A, self).__init__()
- self._a = 'a'
+ self._a = "a"
self._b = b
a = A(b=C())
elt = get_object_as_xml_polymorphic(a, A)
xml_string = etree.tostring(elt, pretty_print=True)
- if six.PY2:
- print(xml_string, end="")
- else:
- sys.stdout.buffer.write(xml_string)
+ sys.stdout.buffer.write(xml_string)
element_tree = etree.fromstring(xml_string)
new_a = get_xml_as_object_polymorphic(elt, A)
@@ -603,26 +639,25 @@ class SomeComplexModel(ComplexModel):
s = Unicode
i = Integer
- v = SomeComplexModel(s='a', i=1),
+ v = (SomeComplexModel(s="a", i=1),)
class SomeService(Service):
@rpc(_returns=SomeComplexModel)
def get(ctx):
return v
- desc = SomeService.public_methods['get']
+ desc = SomeService.public_methods["get"]
ctx = FakeContext(out_object=v, descriptor=desc)
ostr = ctx.out_stream = BytesIO()
- XmlDocument(Application([SomeService], __name__)) \
- .serialize(ctx, XmlDocument.RESPONSE)
+ XmlDocument(Application([SomeService], __name__)).serialize(
+ ctx, XmlDocument.RESPONSE
+ )
elt = etree.fromstring(ostr.getvalue())
print(etree.tostring(elt, pretty_print=True))
- assert elt.xpath('x:getResult/x:i/text()',
- namespaces={'x':__name__}) == ['1']
- assert elt.xpath('x:getResult/x:s/text()',
- namespaces={'x':__name__}) == ['a']
+ assert elt.xpath("x:getResult/x:i/text()", namespaces={"x": __name__}) == ["1"]
+ assert elt.xpath("x:getResult/x:s/text()", namespaces={"x": __name__}) == ["a"]
def test_many(self):
class SomeComplexModel(ComplexModel):
@@ -630,11 +665,11 @@ class SomeComplexModel(ComplexModel):
i = Integer
v = [
- SomeComplexModel(s='a', i=1),
- SomeComplexModel(s='b', i=2),
- SomeComplexModel(s='c', i=3),
- SomeComplexModel(s='d', i=4),
- SomeComplexModel(s='e', i=5),
+ SomeComplexModel(s="a", i=1),
+ SomeComplexModel(s="b", i=2),
+ SomeComplexModel(s="c", i=3),
+ SomeComplexModel(s="d", i=4),
+ SomeComplexModel(s="e", i=5),
]
class SomeService(Service):
@@ -642,20 +677,23 @@ class SomeService(Service):
def get(ctx):
return v
- desc = SomeService.public_methods['get']
+ desc = SomeService.public_methods["get"]
ctx = FakeContext(out_object=[v], descriptor=desc)
ostr = ctx.out_stream = BytesIO()
- XmlDocument(Application([SomeService], __name__)) \
- .serialize(ctx, XmlDocument.RESPONSE)
+ XmlDocument(Application([SomeService], __name__)).serialize(
+ ctx, XmlDocument.RESPONSE
+ )
elt = etree.fromstring(ostr.getvalue())
print(etree.tostring(elt, pretty_print=True))
- assert elt.xpath('x:getResult/x:SomeComplexModel/x:i/text()',
- namespaces={'x': __name__}) == ['1', '2', '3', '4', '5']
- assert elt.xpath('x:getResult/x:SomeComplexModel/x:s/text()',
- namespaces={'x': __name__}) == ['a', 'b', 'c', 'd', 'e']
+ assert elt.xpath(
+ "x:getResult/x:SomeComplexModel/x:i/text()", namespaces={"x": __name__}
+ ) == ["1", "2", "3", "4", "5"]
+ assert elt.xpath(
+ "x:getResult/x:SomeComplexModel/x:s/text()", namespaces={"x": __name__}
+ ) == ["a", "b", "c", "d", "e"]
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/protocol/test_yaml.py b/spyne/test/protocol/test_yaml.py
index 2cb224c8c..a4d1a73a1 100755
--- a/spyne/test/protocol/test_yaml.py
+++ b/spyne/test/protocol/test_yaml.py
@@ -19,16 +19,14 @@
import unittest
-from spyne.test.protocol._test_dictdoc import TDictDocumentTest
-from spyne.protocol.yaml import YamlDocument
-
from spyne import MethodContext
from spyne.application import Application
from spyne.decorator import srpc
-from spyne.service import Service
+from spyne.protocol.yaml import YamlDocument, yaml
from spyne.server import ServerBase
+from spyne.service import Service
+from spyne.test.protocol._test_dictdoc import TDictDocumentTest
-from spyne.protocol.yaml import yaml
yaml.dumps = yaml.dump
yaml.loads = yaml.load
@@ -42,17 +40,20 @@ class SomeService(Service):
def yay():
pass
- app = Application([SomeService], 'tns',
- in_protocol=YamlDocument(),
- out_protocol=YamlDocument())
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=YamlDocument(),
+ out_protocol=YamlDocument(),
+ )
server = ServerBase(app)
initial_ctx = MethodContext(server, MethodContext.SERVER)
- initial_ctx.in_string = [b'{']
- ctx, = server.generate_contexts(initial_ctx)
- assert ctx.in_error.faultcode == 'Client.YamlDecodeError'
+ initial_ctx.in_string = [b"{"]
+ (ctx,) = server.generate_contexts(initial_ctx)
+ assert ctx.in_error.faultcode == "Client.YamlDecodeError"
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/regen_wsdl.py b/spyne/test/regen_wsdl.py
index 2ad5f75d6..b04d0eb7d 100755
--- a/spyne/test/regen_wsdl.py
+++ b/spyne/test/regen_wsdl.py
@@ -1,16 +1,16 @@
#!/usr/bin/env python
from lxml import etree
-from spyne.test.sort_wsdl import sort_wsdl
-from spyne.interface.wsdl import Wsdl11
-from spyne.test.interop.server._service import services
from spyne.application import Application
+from spyne.interface.wsdl import Wsdl11
+from spyne.test.interop.server._service import services
+from spyne.test.sort_wsdl import sort_wsdl
-app = Application(services, 'spyne.test.interop.server')
-app.transport = 'http://schemas.xmlsoap.org/soap/http'
+app = Application(services, "spyne.test.interop.server")
+app.transport = "http://schemas.xmlsoap.org/soap/http"
wsdl = Wsdl11(app.interface)
-wsdl.build_interface_document('http://localhost:9754/')
+wsdl.build_interface_document("http://localhost:9754/")
elt = etree.ElementTree(etree.fromstring(wsdl.get_interface_document()))
sort_wsdl(elt)
s = etree.tostring(elt)
@@ -18,9 +18,10 @@
# minidom's serialization seems to put attributes in alphabetic order.
# this is exactly what we want here.
from xml.dom.minidom import parseString
+
doc = parseString(s)
-s = doc.toprettyxml(indent=' ', newl='\n', encoding='utf8')
-s = s.replace(" xmlns:","\n xmlns:")
+s = doc.toprettyxml(indent=" ", newl="\n", encoding="utf8")
+s = s.replace(" xmlns:", "\n xmlns:")
-open('wsdl.xml', 'w').write(s)
-print('wsdl.xml written')
+open("wsdl.xml", "w").write(s)
+print("wsdl.xml written")
diff --git a/spyne/test/sort_wsdl.py b/spyne/test/sort_wsdl.py
index 96a45810b..4802c89c2 100755
--- a/spyne/test/sort_wsdl.py
+++ b/spyne/test/sort_wsdl.py
@@ -30,13 +30,13 @@
def cache_order(l, ns):
- return dict([ ("{%s}%s" % (ns, a), l.index(a)) for a in l])
+ return dict([("{%s}%s" % (ns, a), l.index(a)) for a in l])
-wsdl_order = ('types', 'message', 'service', 'portType', 'binding')
+wsdl_order = ("types", "message", "service", "portType", "binding")
wsdl_order = cache_order(wsdl_order, ns_wsdl)
-schema_order = ('import', 'element', 'simpleType', 'complexType', 'attribute')
+schema_order = ("import", "element", "simpleType", "complexType", "attribute")
schema_order = cache_order(schema_order, ns_schema)
parser = etree.XMLParser(remove_blank_text=True)
@@ -62,17 +62,21 @@ def sort_wsdl(tree):
l0.append(e)
e.getparent().remove(e)
- l0.sort(key=lambda e: (wsdl_order[e.tag], e.attrib['name']))
+ l0.sort(key=lambda e: (wsdl_order[e.tag], e.attrib["name"]))
for e in l0:
tree.getroot().append(e)
for e in tree.getroot():
- if e.tag in ("{%s}portType" % ns_wsdl, "{%s}binding" % ns_wsdl, "{%s}operation" % ns_wsdl):
+ if e.tag in (
+ "{%s}portType" % ns_wsdl,
+ "{%s}binding" % ns_wsdl,
+ "{%s}operation" % ns_wsdl,
+ ):
nodes = []
for p in e.getchildren():
nodes.append(p)
- nodes.sort(key=lambda e: e.attrib.get('name', '0'))
+ nodes.sort(key=lambda e: e.attrib.get("name", "0"))
for p in nodes:
e.append(p)
@@ -94,11 +98,11 @@ def sort_wsdl(tree):
nodes.append(e)
e.getparent().remove(e)
- nodes.sort(key=lambda e: (schema_order[e.tag], e.attrib.get('name', '\0')))
+ nodes.sort(key=lambda e: (schema_order[e.tag], e.attrib.get("name", "\0")))
for e in nodes:
s.append(e)
-if __name__ == '__main__':
+if __name__ == "__main__":
sys.exit(main())
diff --git a/spyne/test/test_null_server.py b/spyne/test/test_null_server.py
index d127e4ec6..0e6323751 100755
--- a/spyne/test/test_null_server.py
+++ b/spyne/test/test_null_server.py
@@ -22,18 +22,16 @@
from lxml import etree
-from spyne import Ignored
-from spyne import const
-from spyne.interface.wsdl import Wsdl11
-from spyne.protocol.xml import XmlDocument
-
-from spyne.model.complex import Array
-from spyne.model.primitive import Boolean
-from spyne.model.primitive import String
+from spyne import Ignored, const
from spyne.application import Application
from spyne.decorator import srpc
-from spyne.service import Service
+from spyne.interface.wsdl import Wsdl11
+from spyne.model.complex import Array
+from spyne.model.primitive import Boolean, String
+from spyne.protocol.xml import XmlDocument
from spyne.server.null import NullServer
+from spyne.service import Service
+
class TestNullServer(unittest.TestCase):
def test_empty_return_type(self):
@@ -42,8 +40,12 @@ class MessageService(Service):
def send_message(s):
return s
- application = Application([MessageService], 'some_tns',
- in_protocol=XmlDocument(), out_protocol=XmlDocument())
+ application = Application(
+ [MessageService],
+ "some_tns",
+ in_protocol=XmlDocument(),
+ out_protocol=XmlDocument(),
+ )
assert None == NullServer(application).service.send_message("zabaaa")
@@ -61,8 +63,12 @@ def send_message_2(s):
def send_message_3(s):
return "OK"
- application = Application([MessageService], 'some_tns',
- in_protocol=XmlDocument(), out_protocol=XmlDocument())
+ application = Application(
+ [MessageService],
+ "some_tns",
+ in_protocol=XmlDocument(),
+ out_protocol=XmlDocument(),
+ )
server = NullServer(application)
assert Ignored("xyz") == server.service.send_message_1("zabaaa")
@@ -77,8 +83,12 @@ class MessageService(Service):
def send_message(s):
queue.add(s)
- application = Application([MessageService], 'some_tns',
- in_protocol=XmlDocument(), out_protocol=XmlDocument())
+ application = Application(
+ [MessageService],
+ "some_tns",
+ in_protocol=XmlDocument(),
+ out_protocol=XmlDocument(),
+ )
server = NullServer(application)
server.service.send_message("zabaaa")
@@ -91,20 +101,24 @@ def test_call_two_args(self):
class MessageService(Service):
@srpc(String, String)
def send_message(s, k):
- queue.add((s,k))
+ queue.add((s, k))
- application = Application([MessageService], 'some_tns',
- in_protocol=XmlDocument(), out_protocol=XmlDocument())
+ application = Application(
+ [MessageService],
+ "some_tns",
+ in_protocol=XmlDocument(),
+ out_protocol=XmlDocument(),
+ )
server = NullServer(application)
queue.clear()
server.service.send_message("zabaaa", k="hobaa")
- assert set([("zabaaa","hobaa")]) == queue
+ assert set([("zabaaa", "hobaa")]) == queue
queue.clear()
server.service.send_message(k="hobaa")
- assert set([(None,"hobaa")]) == queue
+ assert set([(None, "hobaa")]) == queue
queue.clear()
server.service.send_message("zobaaa", s="hobaa")
@@ -119,20 +133,25 @@ def send_message(s, k):
queue.add((s, k))
return [s, k]
- application = Application([MessageService], 'some_tns',
- in_protocol=XmlDocument(), out_protocol=XmlDocument())
+ application = Application(
+ [MessageService],
+ "some_tns",
+ in_protocol=XmlDocument(),
+ out_protocol=XmlDocument(),
+ )
ostr_server = NullServer(application, ostr=True)
queue.clear()
ret = ostr_server.service.send_message("zabaaa", k="hobaa")
- assert set([("zabaaa","hobaa")]) == queue
- assert etree.fromstring(b''.join(ret)).xpath('//tns:string/text()',
- namespaces=application.interface.nsmap) == ['zabaaa', 'hobaa']
+ assert set([("zabaaa", "hobaa")]) == queue
+ assert etree.fromstring(b"".join(ret)).xpath(
+ "//tns:string/text()", namespaces=application.interface.nsmap
+ ) == ["zabaaa", "hobaa"]
queue.clear()
ostr_server.service.send_message(k="hobaa")
- assert set([(None,"hobaa")]) == queue
+ assert set([(None, "hobaa")]) == queue
queue.clear()
ostr_server.service.send_message("zobaaa", s="hobaa")
@@ -145,24 +164,27 @@ def ping():
return True
application = Application(
- [PingService], 'some_tns',
- in_protocol=XmlDocument(), out_protocol=XmlDocument())
+ [PingService],
+ "some_tns",
+ in_protocol=XmlDocument(),
+ out_protocol=XmlDocument(),
+ )
server = NullServer(application)
origin_collect = gc.collect
origin_MIN_GC_INTERVAL = const.MIN_GC_INTERVAL
try:
- gc.collect = lambda : 1/0
+ gc.collect = lambda: 1 / 0
with self.assertRaises(ZeroDivisionError):
const.MIN_GC_INTERVAL = 0
server.service.ping()
# No raise
- const.MIN_GC_INTERVAL = float('inf')
+ const.MIN_GC_INTERVAL = float("inf")
server.service.ping()
finally:
gc.collect = origin_collect
const.MIN_GC_INTERVAL = origin_MIN_GC_INTERVAL
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/test_service.py b/spyne/test/test_service.py
index ac09aa3d1..684b46be8 100755
--- a/spyne/test/test_service.py
+++ b/spyne/test/test_service.py
@@ -22,31 +22,29 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
import unittest
-
-from spyne.util.six import BytesIO
+from io import BytesIO
from lxml import etree
from spyne import LogicError
-from spyne.const import RESPONSE_SUFFIX
-from spyne.model.primitive import NATIVE_MAP
-
-from spyne.service import Service
-from spyne.decorator import rpc, srpc
from spyne.application import Application
from spyne.auxproc.sync import SyncAuxProc
from spyne.auxproc.thread import ThreadAuxProc
+from spyne.const import RESPONSE_SUFFIX
+from spyne.decorator import rpc, srpc
+from spyne.model import Array, ComplexModel, Iterable, SelfReference, String, Unicode
+from spyne.model.primitive import NATIVE_MAP
from spyne.protocol.http import HttpRpc
from spyne.protocol.soap import Soap11
from spyne.server.null import NullServer
from spyne.server.wsgi import WsgiApplication
-from spyne.model import Array, SelfReference, Iterable, ComplexModel, String, \
- Unicode
+from spyne.service import Service
-Application.transport = 'test'
+Application.transport = "test"
def start_response(code, headers):
@@ -74,6 +72,7 @@ def test_method_exception(self):
def on_method_exception_object(ctx):
assert ctx.out_error is not None
from spyne.protocol.xml import SchemaValidationError
+
assert isinstance(ctx.out_error, SchemaValidationError)
logging.error("method_exception_object: %r", repr(ctx.out_error))
h[0] += 1
@@ -81,9 +80,11 @@ def on_method_exception_object(ctx):
def on_method_exception_document(ctx):
assert ctx.out_error is not None
from spyne.protocol.xml import SchemaValidationError
+
assert isinstance(ctx.out_error, SchemaValidationError)
- logging.error("method_exception_document: %r",
- etree.tostring(ctx.out_document))
+ logging.error(
+ "method_exception_document: %r", etree.tostring(ctx.out_document)
+ )
h[0] += 1
class SomeService(Service):
@@ -91,14 +92,20 @@ class SomeService(Service):
def some_call(ctx, some_str):
print(some_str)
- app = Application([SomeService], "some_tns",
- in_protocol=XmlDocument(validator='lxml'), out_protocol=Soap11())
+ app = Application(
+ [SomeService],
+ "some_tns",
+ in_protocol=XmlDocument(validator="lxml"),
+ out_protocol=Soap11(),
+ )
app.event_manager.add_listener(
- "method_exception_object", on_method_exception_object)
+ "method_exception_object", on_method_exception_object
+ )
app.event_manager.add_listener(
- "method_exception_document", on_method_exception_document)
+ "method_exception_document", on_method_exception_document
+ )
# this shouldn't be called because:
# 1. document isn't validated
@@ -108,7 +115,8 @@ def some_call(ctx, some_str):
# 5. hence; no handlers from the service class is invoked.
# 6. hence; the h[0] == 2 check (instead of 3)
SomeService.event_manager.add_listener(
- "method_exception_object", on_method_exception_object)
+ "method_exception_object", on_method_exception_object
+ )
wsgi_app = WsgiApplication(app)
@@ -118,14 +126,19 @@ def some_call(ctx, some_str):
"""
- _ = b''.join(wsgi_app({
- 'PATH_INFO': '/',
- 'SERVER_NAME': 'localhost',
- 'SERVER_PORT': '7000',
- 'REQUEST_METHOD': 'POST',
- 'wsgi.url_scheme': 'http',
- 'wsgi.input': BytesIO(xml_request),
- }, start_response))
+ _ = b"".join(
+ wsgi_app(
+ {
+ "PATH_INFO": "/",
+ "SERVER_NAME": "localhost",
+ "SERVER_PORT": "7000",
+ "REQUEST_METHOD": "POST",
+ "wsgi.url_scheme": "http",
+ "wsgi.input": BytesIO(xml_request),
+ },
+ start_response,
+ )
+ )
assert h[0] == 2
@@ -133,14 +146,18 @@ def some_call(ctx, some_str):
class TestMultipleMethods(unittest.TestCase):
def test_single_method(self):
try:
- Application([MultipleMethods1, MultipleMethods2], 'tns',
- in_protocol=Soap11(), out_protocol=Soap11())
+ Application(
+ [MultipleMethods1, MultipleMethods2],
+ "tns",
+ in_protocol=Soap11(),
+ out_protocol=Soap11(),
+ )
except ValueError:
pass
else:
- raise Exception('must fail.')
+ raise Exception("must fail.")
def test_simple_aux_nullserver(self):
data = []
@@ -157,20 +174,19 @@ class AuxService(Service):
def call(s):
data.append(s)
- app = Application([SomeService, AuxService], 'tns', 'name', Soap11(),
- Soap11())
+ app = Application([SomeService, AuxService], "tns", "name", Soap11(), Soap11())
server = NullServer(app)
server.service.call("hey")
- assert data == ['hey', 'hey']
+ assert data == ["hey", "hey"]
def test_namespace_in_message_name(self):
class S(Service):
- @srpc(String, _in_message_name='{tns}inMessageName')
+ @srpc(String, _in_message_name="{tns}inMessageName")
def call(s):
pass
- app = Application([S], 'tns', 'name', Soap11(), Soap11())
+ app = Application([S], "tns", "name", Soap11(), Soap11())
def test_simple_aux_wsgi(self):
data = []
@@ -187,23 +203,32 @@ class AuxService(Service):
def call(s):
data.append(s)
- app = Application([SomeService, AuxService], 'tns',
- in_protocol=HttpRpc(), out_protocol=HttpRpc())
+ app = Application(
+ [SomeService, AuxService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HttpRpc(),
+ )
server = WsgiApplication(app)
- server({
- 'QUERY_STRING': 's=hey',
- 'PATH_INFO': '/call',
- 'REQUEST_METHOD': 'POST',
- 'CONTENT_TYPE': 'text/xml; charset=utf8',
- 'SERVER_NAME': 'localhost',
- 'wsgi.input': BytesIO(),
- }, start_response, "http://null")
-
- assert data == ['hey', 'hey']
+ server(
+ {
+ "QUERY_STRING": "s=hey",
+ "PATH_INFO": "/call",
+ "REQUEST_METHOD": "POST",
+ "CONTENT_TYPE": "text/xml; charset=utf8",
+ "SERVER_NAME": "localhost",
+ "wsgi.input": BytesIO(),
+ },
+ start_response,
+ "http://null",
+ )
+
+ assert data == ["hey", "hey"]
def test_thread_aux_wsgi(self):
import logging
+
logging.basicConfig(level=logging.DEBUG)
data = set()
@@ -220,25 +245,35 @@ class AuxService(Service):
def call(s):
data.add(s + "aux")
- app = Application([SomeService, AuxService], 'tns',
- in_protocol=HttpRpc(), out_protocol=HttpRpc())
+ app = Application(
+ [SomeService, AuxService],
+ "tns",
+ in_protocol=HttpRpc(),
+ out_protocol=HttpRpc(),
+ )
server = WsgiApplication(app)
- server({
- 'QUERY_STRING': 's=hey',
- 'PATH_INFO': '/call',
- 'REQUEST_METHOD': 'POST',
- 'CONTENT_TYPE': 'text/xml; charset=utf8',
- 'SERVER_NAME': 'localhost',
- 'wsgi.input': BytesIO(),
- }, start_response, "http://null")
+ server(
+ {
+ "QUERY_STRING": "s=hey",
+ "PATH_INFO": "/call",
+ "REQUEST_METHOD": "POST",
+ "CONTENT_TYPE": "text/xml; charset=utf8",
+ "SERVER_NAME": "localhost",
+ "wsgi.input": BytesIO(),
+ },
+ start_response,
+ "http://null",
+ )
import time
+
time.sleep(1)
- assert data == set(['hey', 'heyaux'])
+ assert data == set(["hey", "heyaux"])
def test_mixing_primary_and_aux_methods(self):
try:
+
class SomeService(Service):
@srpc(String, _returns=String, _aux=ThreadAuxProc())
def call(s):
@@ -247,25 +282,35 @@ def call(s):
@srpc(String, _returns=String)
def mall(s):
pass
+
except Exception:
pass
else:
- raise Exception("must fail with 'Exception: you can't mix aux and "
- "non-aux methods in a single service definition.'")
+ raise Exception(
+ "must fail with 'Exception: you can't mix aux and "
+ "non-aux methods in a single service definition.'"
+ )
def __run_service(self, service):
- app = Application([service], 'tns', in_protocol=HttpRpc(),
- out_protocol=Soap11())
+ app = Application(
+ [service], "tns", in_protocol=HttpRpc(), out_protocol=Soap11()
+ )
server = WsgiApplication(app)
- return_string = b''.join(server({
- 'QUERY_STRING': '',
- 'PATH_INFO': '/some_call',
- 'REQUEST_METHOD': 'POST',
- 'CONTENT_TYPE': 'text/xml; charset=utf8',
- 'SERVER_NAME': 'localhost',
- 'wsgi.input': BytesIO(b""),
- }, start_response, "http://null"))
+ return_string = b"".join(
+ server(
+ {
+ "QUERY_STRING": "",
+ "PATH_INFO": "/some_call",
+ "REQUEST_METHOD": "POST",
+ "CONTENT_TYPE": "text/xml; charset=utf8",
+ "SERVER_NAME": "localhost",
+ "wsgi.input": BytesIO(b""),
+ },
+ start_response,
+ "http://null",
+ )
+ )
elt = etree.fromstring(return_string)
print(etree.tostring(elt, pretty_print=True))
@@ -274,7 +319,7 @@ def __run_service(self, service):
def test_settings_headers_from_user_code(self):
class RespHeader(ComplexModel):
- __namespace__ = 'tns'
+ __namespace__ = "tns"
Elem1 = String
# test header in service definition
@@ -284,74 +329,85 @@ class SomeService(Service):
@rpc()
def some_call(ctx):
ctx.out_header = RespHeader()
- ctx.out_header.Elem1 = 'Test1'
+ ctx.out_header.Elem1 = "Test1"
elt, nsmap = self.__run_service(SomeService)
- query = '/soap11env:Envelope/soap11env:Header/tns:RespHeader' \
- '/tns:Elem1/text()'
+ query = (
+ "/soap11env:Envelope/soap11env:Header/tns:RespHeader" "/tns:Elem1/text()"
+ )
- assert elt.xpath(query, namespaces=nsmap)[0] == 'Test1'
+ assert elt.xpath(query, namespaces=nsmap)[0] == "Test1"
# test header in decorator
class SomeService(Service):
@rpc(_out_header=RespHeader)
def some_call(ctx):
ctx.out_header = RespHeader()
- ctx.out_header.Elem1 = 'Test1'
+ ctx.out_header.Elem1 = "Test1"
elt, nsmap = self.__run_service(SomeService)
- query = '/soap11env:Envelope/soap11env:Header/tns:RespHeader/tns' \
- ':Elem1/text()'
- assert elt.xpath(query, namespaces=nsmap)[0] == 'Test1'
+ query = (
+ "/soap11env:Envelope/soap11env:Header/tns:RespHeader/tns" ":Elem1/text()"
+ )
+ assert elt.xpath(query, namespaces=nsmap)[0] == "Test1"
# test no header
class SomeService(Service):
@rpc()
def some_call(ctx):
ctx.out_header = RespHeader()
- ctx.out_header.Elem1 = 'Test1'
+ ctx.out_header.Elem1 = "Test1"
elt, nsmap = self.__run_service(SomeService)
- query = '/soap11env:Envelope/soap11env:Header/tns:RespHeader' \
- '/tns:Elem1/text()'
+ query = (
+ "/soap11env:Envelope/soap11env:Header/tns:RespHeader" "/tns:Elem1/text()"
+ )
assert len(elt.xpath(query, namespaces=nsmap)) == 0
class TestNativeTypes(unittest.TestCase):
def test_native_types(self):
for t in NATIVE_MAP:
+
class SomeService(Service):
@rpc(t)
def some_call(ctx, arg):
pass
- nt, = SomeService.public_methods['some_call'].in_message \
- ._type_info.values()
+ (nt,) = SomeService.public_methods[
+ "some_call"
+ ].in_message._type_info.values()
assert issubclass(nt, NATIVE_MAP[t])
def test_native_types_in_arrays(self):
for t in NATIVE_MAP:
+
class SomeService(Service):
@rpc(Array(t))
def some_call(ctx, arg):
pass
- nt, = SomeService.public_methods['some_call'].in_message \
- ._type_info.values()
- nt, = nt._type_info.values()
+ (nt,) = SomeService.public_methods[
+ "some_call"
+ ].in_message._type_info.values()
+ (nt,) = nt._type_info.values()
assert issubclass(nt, NATIVE_MAP[t])
class TestBodyStyle(unittest.TestCase):
def test_soap_bare_empty_output(self):
class SomeService(Service):
- @rpc(String, _body_style='bare')
+ @rpc(String, _body_style="bare")
def some_call(ctx, s):
- assert s == 'abc'
+ assert s == "abc"
- app = Application([SomeService], 'tns', in_protocol=Soap11(),
- out_protocol=Soap11(cleanup_namespaces=True))
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=Soap11(),
+ out_protocol=Soap11(cleanup_namespaces=True),
+ )
req = b"""
@@ -170,10 +177,11 @@ def some_method(s):
"""]
- ctx, = server.generate_contexts(ctx)
+ (ctx,) = server.generate_contexts(ctx)
server.get_in_object(ctx)
self.assertEqual(isinstance(ctx.in_error, ValidationError), True)
-if __name__ == '__main__':
+
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/test_sqlalchemy.py b/spyne/test/test_sqlalchemy.py
index 9d7af0df3..b91bdd41f 100755
--- a/spyne/test/test_sqlalchemy.py
+++ b/spyne/test/test_sqlalchemy.py
@@ -18,35 +18,39 @@
#
import logging
+
logging.basicConfig(level=logging.DEBUG)
import inspect
import unittest
-import sqlalchemy
-
from pprint import pprint
-from sqlalchemy import create_engine
-from sqlalchemy import MetaData
-from sqlalchemy import Column
-from sqlalchemy import Table
+import sqlalchemy
+from sqlalchemy import Column, MetaData, Table, create_engine
+from sqlalchemy import text as sa_text
from sqlalchemy.exc import IntegrityError
-
-from sqlalchemy.orm import mapper
-from sqlalchemy.orm import sessionmaker
-
-from spyne import M, Any, Double
-
-from spyne.model import XmlAttribute, File, XmlData, ComplexModel, Array, \
- Integer32, Unicode, Integer, Enum, TTableModel, DateTime, Boolean
-
+from sqlalchemy.orm import registry as _sa_registry
+from sqlalchemy.orm import sessionmaker, with_polymorphic
+
+from spyne import Any, Double, M
+from spyne.model import (
+ Array,
+ Boolean,
+ ComplexModel,
+ DateTime,
+ Enum,
+ File,
+ Integer,
+ Integer32,
+ TTableModel,
+ Unicode,
+ XmlAttribute,
+ XmlData,
+)
from spyne.model.binary import HybridFileStore
-from spyne.model.complex import xml
-from spyne.model.complex import table
-
+from spyne.model.complex import table, xml
from spyne.store.relational import get_pk_columns
-from spyne.store.relational.document import PGJsonB, PGJson, PGFileJson, \
- PGObjectJson
+from spyne.store.relational.document import PGFileJson, PGJson, PGJsonB, PGObjectJson
TableModel = TTableModel()
@@ -62,6 +66,7 @@ class SomeClass1(TableModel):
e = Unicode(32)
from spyne.util.dictdoc import get_dict_as_object
+
inst = get_dict_as_object(dict(i=4), SomeClass1)
assert not sqla_inspect(inst).attrs.e.history.has_changes()
@@ -73,16 +78,16 @@ class SomeClass1(TableModel):
i = Integer32(pk=True)
b = Boolean
- assert isinstance(SomeClass1.Attributes.sqla_table.c.b.type,
- sqlalchemy.Boolean)
+ assert isinstance(SomeClass1.Attributes.sqla_table.c.b.type, sqlalchemy.Boolean)
class SomeClass2(TableModel):
__tablename__ = "%s_%d" % (fn, 2)
i = Integer32(pk=True)
b = Boolean(store_as=int)
- assert isinstance(SomeClass2.Attributes.sqla_table.c.b.type,
- sqlalchemy.SmallInteger)
+ assert isinstance(
+ SomeClass2.Attributes.sqla_table.c.b.type, sqlalchemy.SmallInteger
+ )
def test_jsonb(self):
fn = inspect.stack()[0][3]
@@ -90,24 +95,24 @@ def test_jsonb(self):
class SomeClass1(TableModel):
__tablename__ = "%s_%d" % (fn, 1)
i = Integer32(pk=True)
- a = Any(store_as='json')
+ a = Any(store_as="json")
assert isinstance(SomeClass1.Attributes.sqla_table.c.a.type, PGJson)
class SomeClass2(TableModel):
__tablename__ = "%s_%d" % (fn, 2)
i = Integer32(pk=True)
- a = Any(store_as='jsonb')
+ a = Any(store_as="jsonb")
assert isinstance(SomeClass2.Attributes.sqla_table.c.a.type, PGJsonB)
class SomeClass3(TableModel):
__tablename__ = "%s_%d" % (fn, 3)
i = Integer32(pk=True)
- a = File(store_as=HybridFileStore("path", db_format='jsonb'))
+ a = File(store_as=HybridFileStore("path", db_format="jsonb"))
assert isinstance(SomeClass3.Attributes.sqla_table.c.a.type, PGFileJson)
- assert SomeClass3.Attributes.sqla_table.c.a.type.dbt == 'jsonb'
+ assert SomeClass3.Attributes.sqla_table.c.a.type.dbt == "jsonb"
def test_obj_json(self):
fn = inspect.stack()[0][3]
@@ -119,31 +124,28 @@ class SomeClass(ComplexModel):
class SomeClass1(TableModel):
__tablename__ = "%s_%d" % (fn, 1)
_type_info = [
- ('i', Integer32(pk=True)),
- ('a', Array(SomeClass, store_as='json')),
+ ("i", Integer32(pk=True)),
+ ("a", Array(SomeClass, store_as="json")),
]
- assert isinstance(SomeClass1.Attributes.sqla_table.c.a.type,
- PGObjectJson)
+ assert isinstance(SomeClass1.Attributes.sqla_table.c.a.type, PGObjectJson)
class SomeClass2(TableModel):
__tablename__ = "%s_%d" % (fn, 2)
i = Integer32(pk=True)
- a = SomeClass.customize(store_as='json')
+ a = SomeClass.customize(store_as="json")
- assert isinstance(SomeClass2.Attributes.sqla_table.c.a.type,
- PGObjectJson)
+ assert isinstance(SomeClass2.Attributes.sqla_table.c.a.type, PGObjectJson)
class TestSqlAlchemySchema(unittest.TestCase):
def setUp(self):
- logging.getLogger('sqlalchemy').setLevel(logging.DEBUG)
+ logging.getLogger("sqlalchemy").setLevel(logging.WARNING)
- self.engine = create_engine('sqlite:///:memory:')
- self.session = sessionmaker(bind=self.engine)()
+ self.engine = create_engine("sqlite:///:memory:")
+ self.session = sessionmaker(self.engine)()
self.metadata = TableModel.Attributes.sqla_metadata = MetaData()
- self.metadata.bind = self.engine
- logging.info('Testing against sqlalchemy-%s', sqlalchemy.__version__)
+ logging.info("Testing against sqlalchemy-%s", sqlalchemy.__version__)
def test_obj_json_dirty(self):
fn = inspect.stack()[0][3]
@@ -155,11 +157,11 @@ class SomeClass(ComplexModel):
class SomeClass1(TableModel):
__tablename__ = "%s_%d" % (fn, 1)
_type_info = [
- ('i', Integer32(pk=True)),
- ('a', SomeClass.store_as('jsonb')),
+ ("i", Integer32(pk=True)),
+ ("a", SomeClass.store_as("jsonb")),
]
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
sc1 = SomeClass1(i=5, a=SomeClass(s="s", d=42.0))
self.session.add(sc1)
@@ -169,7 +171,7 @@ class SomeClass1(TableModel):
# TODO: maybe do the flag_modified() on setitem?
sc1.a.s = "ss"
- flag_modified(sc1, 'a')
+ flag_modified(sc1, "a")
assert sc1 in self.session.dirty
@@ -177,13 +179,13 @@ class SomeClass1(TableModel):
assert sc1.a.s == "ss"
# not implemented
- #sc1.a[0].s = "sss"
- #flag_modified(sc1.a[0], 's')
- #assert sc1.a[0] in self.session.dirty
+ # sc1.a[0].s = "sss"
+ # flag_modified(sc1.a[0], 's')
+ # assert sc1.a[0] in self.session.dirty
def test_schema(self):
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True, autoincrement=False)
@@ -191,199 +193,196 @@ class SomeClass(TableModel):
i = Integer32(64, index=True)
t = SomeClass.__table__
- self.metadata.create_all() # not needed, just nice to see.
+ self.metadata.create_all(self.engine) # not needed, just nice to see.
assert t.c.id.primary_key == True
assert t.c.id.autoincrement == False
indexes = list(t.indexes)
indexes.sort(key=lambda idx: idx.name)
for idx in indexes:
- assert 'i' in idx.columns or 's' in idx.columns
- if 's' in idx.columns:
+ assert "i" in idx.columns or "s" in idx.columns
+ if "s" in idx.columns:
assert idx.unique
def test_colname_simple(self):
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True, autoincrement=False)
- s = Unicode(64, sqla_column_args=dict(name='ss'))
+ s = Unicode(64, sqla_column_args=dict(name="ss"))
t = SomeClass.__table__
- self.metadata.create_all() # not needed, just nice to see.
+ self.metadata.create_all(self.engine) # not needed, just nice to see.
- assert 'ss' in t.c
+ assert "ss" in t.c
def test_colname_complex_table(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_other_class'
+ __tablename__ = "some_other_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
- __table_args__ = (
- {"sqlite_autoincrement": True},
- )
+ __tablename__ = "some_class"
+ __table_args__ = ({"sqlite_autoincrement": True},)
id = Integer32(primary_key=True)
- o = SomeOtherClass.customize(store_as='table',
- sqla_column_args=dict(name='oo'))
+ o = SomeOtherClass.customize(
+ store_as="table", sqla_column_args=dict(name="oo")
+ )
t = SomeClass.__table__
- self.metadata.create_all() # not needed, just nice to see.
+ self.metadata.create_all(self.engine) # not needed, just nice to see.
- assert 'oo_id' in t.c
+ assert "oo_id" in t.c
def test_colname_complex_json(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_other_class'
+ __tablename__ = "some_other_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
- __table_args__ = (
- {"sqlite_autoincrement": True},
- )
+ __tablename__ = "some_class"
+ __table_args__ = ({"sqlite_autoincrement": True},)
id = Integer32(primary_key=True)
- o = SomeOtherClass.customize(store_as='json',
- sqla_column_args=dict(name='oo'))
+ o = SomeOtherClass.customize(
+ store_as="json", sqla_column_args=dict(name="oo")
+ )
t = SomeClass.__table__
- self.metadata.create_all() # not needed, just nice to see.
+ self.metadata.create_all(self.engine) # not needed, just nice to see.
- assert 'oo' in t.c
+ assert "oo" in t.c
def test_nested_sql(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_other_class'
+ __tablename__ = "some_other_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
- __table_args__ = (
- {"sqlite_autoincrement": True},
- )
+ __tablename__ = "some_class"
+ __table_args__ = ({"sqlite_autoincrement": True},)
id = Integer32(primary_key=True)
- o = SomeOtherClass.customize(store_as='table')
+ o = SomeOtherClass.customize(store_as="table")
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- soc = SomeOtherClass(s='ehe')
+ soc = SomeOtherClass(s="ehe")
sc = SomeClass(o=soc)
self.session.add(sc)
self.session.commit()
self.session.close()
- sc_db = self.session.query(SomeClass).get(1)
+ sc_db = self.session.get(SomeClass, 1)
print(sc_db)
- assert sc_db.o.s == 'ehe'
+ assert sc_db.o.s == "ehe"
assert sc_db.o_id == 1
sc_db.o = None
self.session.commit()
self.session.close()
- sc_db = self.session.query(SomeClass).get(1)
+ sc_db = self.session.get(SomeClass, 1)
assert sc_db.o == None
assert sc_db.o_id == None
def test_nested_sql_array_as_table(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_other_class'
+ __tablename__ = "some_other_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
- others = Array(SomeOtherClass, store_as='table')
+ others = Array(SomeOtherClass, store_as="table")
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- soc1 = SomeOtherClass(s='ehe1')
- soc2 = SomeOtherClass(s='ehe2')
+ soc1 = SomeOtherClass(s="ehe1")
+ soc2 = SomeOtherClass(s="ehe2")
sc = SomeClass(others=[soc1, soc2])
self.session.add(sc)
self.session.commit()
self.session.close()
- sc_db = self.session.query(SomeClass).get(1)
+ sc_db = self.session.get(SomeClass, 1)
- assert sc_db.others[0].s == 'ehe1'
- assert sc_db.others[1].s == 'ehe2'
+ assert sc_db.others[0].s == "ehe1"
+ assert sc_db.others[1].s == "ehe2"
self.session.close()
def test_nested_sql_array_as_multi_table(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_other_class'
+ __tablename__ = "some_other_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
others = Array(SomeOtherClass, store_as=table(multi=True))
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- soc1 = SomeOtherClass(s='ehe1')
- soc2 = SomeOtherClass(s='ehe2')
+ soc1 = SomeOtherClass(s="ehe1")
+ soc2 = SomeOtherClass(s="ehe2")
sc = SomeClass(others=[soc1, soc2])
self.session.add(sc)
self.session.commit()
self.session.close()
- sc_db = self.session.query(SomeClass).get(1)
+ sc_db = self.session.get(SomeClass, 1)
- assert sc_db.others[0].s == 'ehe1'
- assert sc_db.others[1].s == 'ehe2'
+ assert sc_db.others[0].s == "ehe1"
+ assert sc_db.others[1].s == "ehe2"
self.session.close()
def test_nested_sql_array_as_multi_table_with_backref(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_other_class'
+ __tablename__ = "some_other_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
- others = Array(SomeOtherClass,
- store_as=table(multi=True, backref='some_classes'))
+ others = Array(
+ SomeOtherClass, store_as=table(multi=True, backref="some_classes")
+ )
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- soc1 = SomeOtherClass(s='ehe1')
- soc2 = SomeOtherClass(s='ehe2')
+ soc1 = SomeOtherClass(s="ehe1")
+ soc2 = SomeOtherClass(s="ehe2")
sc = SomeClass(others=[soc1, soc2])
self.session.add(sc)
@@ -403,26 +402,26 @@ class SomeOtherClass(ComplexModel):
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
- others = Array(SomeOtherClass, store_as='xml')
+ others = Array(SomeOtherClass, store_as="xml")
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- soc1 = SomeOtherClass(s='ehe1')
- soc2 = SomeOtherClass(s='ehe2')
+ soc1 = SomeOtherClass(s="ehe1")
+ soc2 = SomeOtherClass(s="ehe2")
sc = SomeClass(others=[soc1, soc2])
self.session.add(sc)
self.session.commit()
self.session.close()
- sc_db = self.session.query(SomeClass).get(1)
+ sc_db = self.session.get(SomeClass, 1)
- assert sc_db.others[0].s == 'ehe1'
- assert sc_db.others[1].s == 'ehe2'
+ assert sc_db.others[0].s == "ehe1"
+ assert sc_db.others[1].s == "ehe2"
self.session.close()
@@ -432,54 +431,58 @@ class SomeOtherClass(ComplexModel):
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
others = Array(SomeOtherClass, store_as=xml(no_ns=True))
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- soc1 = SomeOtherClass(s='ehe1')
- soc2 = SomeOtherClass(s='ehe2')
+ soc1 = SomeOtherClass(s="ehe1")
+ soc2 = SomeOtherClass(s="ehe2")
sc = SomeClass(others=[soc1, soc2])
self.session.add(sc)
self.session.commit()
self.session.close()
- sc_xml = self.session.connection() \
- .execute("select others from some_class") .fetchall()[0][0]
+ sc_xml = (
+ self.session.connection()
+ .execute(sa_text("select others from some_class"))
+ .fetchall()[0][0]
+ )
from lxml import etree
- assert etree.fromstring(sc_xml).tag == 'SomeOtherClassArray'
+
+ assert etree.fromstring(sc_xml).tag == "SomeOtherClassArray"
self.session.close()
def test_inheritance(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_other_class'
+ __tablename__ = "some_other_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class SomeClass(SomeOtherClass):
- numbers = Array(Integer32).store_as(xml(no_ns=True, root_tag='a'))
+ numbers = Array(Integer32).store_as(xml(no_ns=True, root_tag="a"))
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- sc = SomeClass(id=5, s='s', numbers=[1, 2, 3, 4])
+ sc = SomeClass(id=5, s="s", numbers=[1, 2, 3, 4])
self.session.add(sc)
self.session.commit()
self.session.close()
- sc_db = self.session.query(SomeClass).get(5)
+ sc_db = self.session.get(SomeClass, 5)
assert sc_db.numbers == [1, 2, 3, 4]
self.session.close()
- sc_db = self.session.query(SomeOtherClass).get(5)
+ sc_db = self.session.get(SomeOtherClass, 5)
assert sc_db.id == 5
try:
sc_db.numbers
@@ -492,29 +495,29 @@ class SomeClass(SomeOtherClass):
def test_inheritance_with_complex_fields(self):
class Foo(TableModel):
- __tablename__ = 'foo'
+ __tablename__ = "foo"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class Bar(TableModel):
- __tablename__ = 'bar'
+ __tablename__ = "bar"
__table_args__ = {"sqlite_autoincrement": True}
__mapper_args__ = {
- 'polymorphic_on': 'type',
- 'polymorphic_identity': 'bar',
- 'with_polymorphic': '*',
+ "polymorphic_on": "type",
+ "polymorphic_identity": "bar",
+ "with_polymorphic": "*",
}
id = Integer32(primary_key=True)
s = Unicode(64)
type = Unicode(6)
- foos = Array(Foo).store_as('table')
+ foos = Array(Foo).store_as("table")
class SubBar(Bar):
__mapper_args__ = {
- 'polymorphic_identity': 'subbar',
+ "polymorphic_identity": "subbar",
}
i = Integer32
@@ -525,38 +528,40 @@ class SubBar(Bar):
assert not mapper_subbar.concrete
for inheriting in mapper_subbar.iterate_to_root():
- if inheriting is not mapper_subbar \
- and not (mapper_bar.relationships['foos'] is
- mapper_subbar.relationships['foos']):
- raise Exception("Thou shalt stop children relationships "
- "from overriding the ones in parent")
+ if inheriting is not mapper_subbar and not (
+ mapper_bar.relationships["foos"] is mapper_subbar.relationships["foos"]
+ ):
+ raise Exception(
+ "Thou shalt stop children relationships "
+ "from overriding the ones in parent"
+ )
def test_mixins_with_complex_fields(self):
class Foo(TableModel):
- __tablename__ = 'foo'
+ __tablename__ = "foo"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class Bar(TableModel):
- __tablename__ = 'bar'
+ __tablename__ = "bar"
__table_args__ = {"sqlite_autoincrement": True}
__mixin__ = True
__mapper_args__ = {
- 'polymorphic_on': 'type',
- 'polymorphic_identity': 'bar',
- 'with_polymorphic': '*',
+ "polymorphic_on": "type",
+ "polymorphic_identity": "bar",
+ "with_polymorphic": "*",
}
id = Integer32(primary_key=True)
s = Unicode(64)
type = Unicode(6)
- foos = Array(Foo).store_as('table')
+ foos = Array(Foo).store_as("table")
class SubBar(Bar):
__mapper_args__ = {
- 'polymorphic_identity': 'subbar',
+ "polymorphic_identity": "subbar",
}
i = Integer32
@@ -567,11 +572,13 @@ class SubBar(Bar):
assert not mapper_subbar.concrete
for inheriting in mapper_subbar.iterate_to_root():
- if inheriting is not mapper_subbar \
- and not (mapper_bar.relationships['foos'] is
- mapper_subbar.relationships['foos']):
- raise Exception("Thou shalt stop children relationships "
- "from overriding the ones in parent")
+ if inheriting is not mapper_subbar and not (
+ mapper_bar.relationships["foos"] is mapper_subbar.relationships["foos"]
+ ):
+ raise Exception(
+ "Thou shalt stop children relationships "
+ "from overriding the ones in parent"
+ )
def test_sqlalchemy_inheritance(self):
# no spyne code is involved here.
@@ -591,8 +598,7 @@ def __init__(self, name, manager_data):
def __repr__(self):
return (
- self.__class__.__name__ + " " +
- self.name + " " + self.manager_data
+ self.__class__.__name__ + " " + self.name + " " + self.manager_data
)
class Engineer(Employee):
@@ -602,44 +608,50 @@ def __init__(self, name, engineer_info):
def __repr__(self):
return (
- self.__class__.__name__ + " " +
- self.name + " " + self.engineer_info
+ self.__class__.__name__ + " " + self.name + " " + self.engineer_info
)
- employees_table = Table('employees', self.metadata,
- Column('employee_id', sqlalchemy.Integer, primary_key=True),
- Column('name', sqlalchemy.String(50)),
- Column('manager_data', sqlalchemy.String(50)),
- Column('engineer_info', sqlalchemy.String(50)),
- Column('type', sqlalchemy.String(20), nullable=False),
+ employees_table = Table(
+ "employees",
+ self.metadata,
+ Column("employee_id", sqlalchemy.Integer, primary_key=True),
+ Column("name", sqlalchemy.String(50)),
+ Column("manager_data", sqlalchemy.String(50)),
+ Column("engineer_info", sqlalchemy.String(50)),
+ Column("type", sqlalchemy.String(20), nullable=False),
)
- employee_mapper = mapper(Employee, employees_table,
- polymorphic_on=employees_table.c.type,
- polymorphic_identity='employee')
+ _reg = _sa_registry()
+ employee_mapper = _reg.map_imperatively(
+ Employee,
+ employees_table,
+ polymorphic_on=employees_table.c.type,
+ polymorphic_identity="employee",
+ )
- manager_mapper = mapper(Manager, inherits=employee_mapper,
- polymorphic_identity='manager')
+ manager_mapper = _reg.map_imperatively(
+ Manager, inherits=employee_mapper, polymorphic_identity="manager"
+ )
- engineer_mapper = mapper(Engineer, inherits=employee_mapper,
- polymorphic_identity='engineer')
+ engineer_mapper = _reg.map_imperatively(
+ Engineer, inherits=employee_mapper, polymorphic_identity="engineer"
+ )
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- manager = Manager('name', 'data')
+ manager = Manager("name", "data")
self.session.add(manager)
self.session.commit()
self.session.close()
- assert self.session.query(Employee).with_polymorphic('*') \
- .filter_by(employee_id=1) \
- .one().type == 'manager'
+ poly = with_polymorphic(Employee, "*")
+ assert self.session.query(poly).filter_by(employee_id=1).one().type == "manager"
def test_inheritance_polymorphic_with_non_nullables_in_subclasses(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_other_class'
+ __tablename__ = "some_other_class"
__table_args__ = {"sqlite_autoincrement": True}
- __mapper_args__ = {'polymorphic_on': 't', 'polymorphic_identity': 1}
+ __mapper_args__ = {"polymorphic_on": "t", "polymorphic_identity": 1}
id = Integer32(primary_key=True)
t = Integer32(nillable=False)
@@ -648,12 +660,12 @@ class SomeOtherClass(TableModel):
class SomeClass(SomeOtherClass):
__mapper_args__ = (
(),
- {'polymorphic_identity': 2},
+ {"polymorphic_identity": 2},
)
i = Integer(nillable=False)
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
assert SomeOtherClass.__table__.c.s.nullable == False
@@ -663,7 +675,7 @@ class SomeClass(SomeOtherClass):
# well.
assert SomeOtherClass.__table__.c.i.nullable == True
- soc = SomeOtherClass(s='s')
+ soc = SomeOtherClass(s="s")
self.session.add(soc)
self.session.commit()
soc_id = soc.id
@@ -677,41 +689,41 @@ class SomeClass(SomeOtherClass):
else:
raise Exception("Must fail with IntegrityError.")
- sc2 = SomeClass(s='s') # this won't fail. should it?
+ sc2 = SomeClass(s="s") # this won't fail. should it?
self.session.add(sc2)
self.session.commit()
self.session.expunge_all()
- assert self.session.query(SomeOtherClass).with_polymorphic('*') \
- .filter_by(id=soc_id).one().t == 1
+ poly = with_polymorphic(SomeOtherClass, "*")
+ assert self.session.query(poly).filter_by(id=soc_id).one().t == 1
self.session.close()
def test_inheritance_polymorphic(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
- __mapper_args__ = {'polymorphic_on': 't', 'polymorphic_identity': 1}
+ __mapper_args__ = {"polymorphic_on": "t", "polymorphic_identity": 1}
id = Integer32(primary_key=True)
s = Unicode(64)
t = Integer32(nillable=False)
class SomeClass(SomeOtherClass):
- __mapper_args__ = {'polymorphic_identity': 2}
- numbers = Array(Integer32).store_as(xml(no_ns=True, root_tag='a'))
+ __mapper_args__ = {"polymorphic_identity": 2}
+ numbers = Array(Integer32).store_as(xml(no_ns=True, root_tag="a"))
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- sc = SomeClass(id=5, s='s', numbers=[1, 2, 3, 4])
+ sc = SomeClass(id=5, s="s", numbers=[1, 2, 3, 4])
self.session.add(sc)
self.session.commit()
self.session.close()
- assert self.session.query(SomeOtherClass).with_polymorphic('*') \
- .filter_by(id=5).one().t == 2
+ poly = with_polymorphic(SomeOtherClass, "*")
+ assert self.session.query(poly).filter_by(id=5).one().t == 2
self.session.close()
def test_nested_sql_array_as_json(self):
@@ -720,45 +732,45 @@ class SomeOtherClass(ComplexModel):
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
- others = Array(SomeOtherClass, store_as='json')
+ others = Array(SomeOtherClass, store_as="json")
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- soc1 = SomeOtherClass(s='ehe1')
- soc2 = SomeOtherClass(s='ehe2')
+ soc1 = SomeOtherClass(s="ehe1")
+ soc2 = SomeOtherClass(s="ehe2")
sc = SomeClass(others=[soc1, soc2])
self.session.add(sc)
self.session.commit()
self.session.close()
- sc_db = self.session.query(SomeClass).get(1)
+ sc_db = self.session.get(SomeClass, 1)
- assert sc_db.others[0].s == 'ehe1'
- assert sc_db.others[1].s == 'ehe2'
+ assert sc_db.others[0].s == "ehe1"
+ assert sc_db.others[1].s == "ehe2"
self.session.close()
def test_modifiers(self):
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
i = XmlAttribute(Integer32(pk=True))
s = XmlData(Unicode(64))
- self.metadata.create_all()
- self.session.add(SomeClass(s='s'))
+ self.metadata.create_all(self.engine)
+ self.session.add(SomeClass(s="s"))
self.session.commit()
self.session.expunge_all()
- ret = self.session.query(SomeClass).get(1)
+ ret = self.session.get(SomeClass, 1)
assert ret.i == 1 # redundant
- assert ret.s == 's'
+ assert ret.s == "s"
def test_default_ctor(self):
class SomeOtherClass(ComplexModel):
@@ -766,29 +778,29 @@ class SomeOtherClass(ComplexModel):
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
- others = Array(SomeOtherClass, store_as='json')
- f = Unicode(32, default='uuu')
+ others = Array(SomeOtherClass, store_as="json")
+ f = Unicode(32, default="uuu")
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
self.session.add(SomeClass())
self.session.commit()
self.session.expunge_all()
- assert self.session.query(SomeClass).get(1).f == 'uuu'
+ assert self.session.get(SomeClass, 1).f == "uuu"
def test_default_value(self):
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
- f = Unicode(32, db_default=u'uuu')
+ f = Unicode(32, db_default="uuu")
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
val = SomeClass()
assert val.f is None
@@ -797,96 +809,96 @@ class SomeClass(TableModel):
self.session.expunge_all()
- assert self.session.query(SomeClass).get(1).f == u'uuu'
+ assert self.session.get(SomeClass, 1).f == "uuu"
def test_default_ctor_with_sql_relationship(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_other_class'
+ __tablename__ = "some_other_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
- o = SomeOtherClass.customize(store_as='table')
+ o = SomeOtherClass.customize(store_as="table")
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
self.session.add(SomeClass())
self.session.commit()
def test_store_as_index(self):
class SomeOtherClass(TableModel):
- __tablename__ = 'some_other_class'
+ __tablename__ = "some_other_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
s = Unicode(64)
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
__table_args__ = {"sqlite_autoincrement": True}
id = Integer32(primary_key=True)
- o = SomeOtherClass.customize(store_as='table', index='btree')
+ o = SomeOtherClass.customize(store_as="table", index="btree")
- self.metadata.create_all()
- idx, = SomeClass.__table__.indexes
- assert 'o_id' in idx.columns
+ self.metadata.create_all(self.engine)
+ (idx,) = SomeClass.__table__.indexes
+ assert "o_id" in idx.columns
def test_scalar_collection(self):
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
id = Integer32(primary_key=True)
- values = Array(Unicode).store_as('table')
+ values = Array(Unicode).store_as("table")
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
- self.session.add(SomeClass(id=1, values=['a', 'b', 'c']))
+ self.session.add(SomeClass(id=1, values=["a", "b", "c"]))
self.session.commit()
- sc = self.session.query(SomeClass).get(1)
- assert sc.values == ['a', 'b', 'c']
+ sc = self.session.get(SomeClass, 1)
+ assert sc.values == ["a", "b", "c"]
del sc
- sc = self.session.query(SomeClass).get(1)
- sc.values.append('d')
+ sc = self.session.get(SomeClass, 1)
+ sc.values.append("d")
self.session.commit()
del sc
- sc = self.session.query(SomeClass).get(1)
- assert sc.values == ['a', 'b', 'c', 'd']
+ sc = self.session.get(SomeClass, 1)
+ assert sc.values == ["a", "b", "c", "d"]
- sc = self.session.query(SomeClass).get(1)
+ sc = self.session.get(SomeClass, 1)
sc.values = sc.values[1:]
self.session.commit()
del sc
- sc = self.session.query(SomeClass).get(1)
- assert sc.values == ['b', 'c', 'd']
+ sc = self.session.get(SomeClass, 1)
+ assert sc.values == ["b", "c", "d"]
def test_multiple_fk(self):
class SomeChildClass(TableModel):
- __tablename__ = 'some_child_class'
+ __tablename__ = "some_child_class"
id = Integer32(primary_key=True)
s = Unicode(64)
i = Integer32
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
id = Integer32(primary_key=True)
- children = Array(SomeChildClass).store_as('table')
- mirror = SomeChildClass.store_as('table')
+ children = Array(SomeChildClass).store_as("table")
+ mirror = SomeChildClass.store_as("table")
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
children = [
- SomeChildClass(s='p', i=600),
- SomeChildClass(s='|', i=10),
- SomeChildClass(s='q', i=9),
+ SomeChildClass(s="p", i=600),
+ SomeChildClass(s="|", i=10),
+ SomeChildClass(s="q", i=9),
]
sc = SomeClass(children=children)
@@ -896,111 +908,115 @@ class SomeClass(TableModel):
self.session.commit()
del sc
- sc = self.session.query(SomeClass).get(1)
- assert ''.join([scc.s for scc in sc.children]) == 'p|q'
+ sc = self.session.get(SomeClass, 1)
+ assert "".join([scc.s for scc in sc.children]) == "p|q"
assert sum([scc.i for scc in sc.children]) == 619
def test_simple_fk(self):
class SomeChildClass(TableModel):
- __tablename__ = 'some_child_class'
+ __tablename__ = "some_child_class"
id = Integer32(primary_key=True)
s = Unicode(64)
i = Integer32
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
id = Integer32(primary_key=True)
- child_id = Integer32(fk='some_child_class.id')
+ child_id = Integer32(fk="some_child_class.id")
- foreign_keys = SomeClass.__table__.c['child_id'].foreign_keys
+ foreign_keys = SomeClass.__table__.c["child_id"].foreign_keys
assert len(foreign_keys) == 1
- fk, = foreign_keys
- assert fk._colspec == 'some_child_class.id'
+ (fk,) = foreign_keys
+ assert fk._colspec == "some_child_class.id"
def test_multirel_single_table(self):
class SomeChildClass(TableModel):
- __tablename__ = 'some_child_class'
+ __tablename__ = "some_child_class"
id = Integer32(primary_key=True)
s = Unicode(64)
class SomeOtherChildClass(TableModel):
- __tablename__ = 'some_other_child_class'
+ __tablename__ = "some_other_child_class"
id = Integer32(primary_key=True)
i = Integer32
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
id = Integer32(primary_key=True)
- children = Array(SomeChildClass,
+ children = Array(
+ SomeChildClass,
store_as=table(
- multi='children', lazy='joined',
- left='parent_id', right='child_id',
- fk_left_ondelete='cascade',
- fk_right_ondelete='cascade',
+ multi="children",
+ lazy="joined",
+ left="parent_id",
+ right="child_id",
+ fk_left_ondelete="cascade",
+ fk_right_ondelete="cascade",
),
)
- other_children = Array(SomeOtherChildClass,
+ other_children = Array(
+ SomeOtherChildClass,
store_as=table(
- multi='children', lazy='joined',
- left='parent_id', right='other_child_id',
- fk_left_ondelete='cascade',
- fk_right_ondelete='cascade',
+ multi="children",
+ lazy="joined",
+ left="parent_id",
+ right="other_child_id",
+ fk_left_ondelete="cascade",
+ fk_right_ondelete="cascade",
),
)
- t = SomeClass.Attributes.sqla_metadata.tables['children']
+ t = SomeClass.Attributes.sqla_metadata.tables["children"]
- fkp, = t.c.parent_id.foreign_keys
- assert fkp._colspec == 'some_class.id'
+ (fkp,) = t.c.parent_id.foreign_keys
+ assert fkp._colspec == "some_class.id"
- fkc, = t.c.child_id.foreign_keys
- assert fkc._colspec == 'some_child_class.id'
+ (fkc,) = t.c.child_id.foreign_keys
+ assert fkc._colspec == "some_child_class.id"
- fkoc, = t.c.other_child_id.foreign_keys
- assert fkoc._colspec == 'some_other_child_class.id'
+ (fkoc,) = t.c.other_child_id.foreign_keys
+ assert fkoc._colspec == "some_other_child_class.id"
def test_reflection(self):
class SomeClass(TableModel):
- __tablename__ = 'some_class'
+ __tablename__ = "some_class"
id = Integer32(primary_key=True)
s = Unicode(32)
- TableModel.Attributes.sqla_metadata.create_all()
+ TableModel.Attributes.sqla_metadata.create_all(self.engine)
# create a new table model with empty metadata
TM2 = TTableModel()
- TM2.Attributes.sqla_metadata.bind = self.engine
-
# fill it with information from the db
- TM2.Attributes.sqla_metadata.reflect()
+ TM2.Attributes.sqla_metadata.reflect(bind=self.engine)
# convert sqla info to spyne info
class Reflected(TM2):
- __table__ = TM2.Attributes.sqla_metadata.tables['some_class']
+ __table__ = TM2.Attributes.sqla_metadata.tables["some_class"]
pprint(dict(Reflected._type_info).items())
- assert issubclass(Reflected._type_info['id'], Integer)
+ assert issubclass(Reflected._type_info["id"], Integer)
# this looks at spyne attrs
- assert [k for k, v in get_pk_columns(Reflected)] == ['id']
+ assert [k for k, v in get_pk_columns(Reflected)] == ["id"]
# this looks at sqla attrs
- assert [k for k, v in Reflected.get_primary_keys()] == ['id']
+ assert [k for k, v in Reflected.get_primary_keys()] == ["id"]
- assert issubclass(Reflected._type_info['s'], Unicode)
- assert Reflected._type_info['s'].Attributes.max_len == 32
+ assert issubclass(Reflected._type_info["s"], Unicode)
+ assert Reflected._type_info["s"].Attributes.max_len == 32
def _test_sqlalchemy_remapping(self):
class SomeTable(TableModel):
- __tablename__ = 'some_table'
+ __tablename__ = "some_table"
id = Integer32(pk=True)
i = Integer32
s = Unicode(32)
@@ -1013,21 +1029,22 @@ class SomeTableSubset(TableModel):
class SomeTableOtherSubset(TableModel):
__table__ = SomeTable.__table__
- _type_info = [(k, v) for k, v in SomeTable._type_info.items()
- if k in ('id', 's')]
+ _type_info = [
+ (k, v) for k, v in SomeTable._type_info.items() if k in ("id", "s")
+ ]
- self.session.add(SomeTable(id=1, i=2, s='s'))
+ self.session.add(SomeTable(id=1, i=2, s="s"))
self.session.commit()
- st = self.session.query(SomeTable).get(1)
- sts = self.session.query(SomeTableSubset).get(1)
- stos = self.session.query(SomeTableOtherSubset).get(1)
+ st = self.session.get(SomeTable, 1)
+ sts = self.session.get(SomeTableSubset, 1)
+ stos = self.session.get(SomeTableOtherSubset, 1)
sts.i = 3
- sts.s = 'ss' # will not be flushed to db
+ sts.s = "ss" # will not be flushed to db
self.session.commit()
- assert st.s == 's'
+ assert st.s == "s"
assert stos.i == 3
def test_file_storage(self):
@@ -1035,15 +1052,15 @@ class C(TableModel):
__tablename__ = "c"
id = Integer32(pk=True)
- f = File(store_as=HybridFileStore('test_file_storage', 'json'))
+ f = File(store_as=HybridFileStore("test_file_storage", "json"))
- self.metadata.create_all()
- c = C(f=File.Value(name=u"name", type=u"type", data=[b"data"]))
+ self.metadata.create_all(self.engine)
+ c = C(f=File.Value(name="name", type="type", data=[b"data"]))
self.session.add(c)
self.session.flush()
self.session.commit()
- c = self.session.query(C).get(1)
+ c = self.session.get(C, 1)
print(c)
assert c.f.name == "name"
assert c.f.type == "type"
@@ -1057,10 +1074,10 @@ class C(TableModel):
class D(TableModel):
__tablename__ = "d"
d = Integer32(pk=True)
- c = C.store_as('table')
+ c = C.store_as("table")
- C.append_field('d', D.store_as('table'))
- assert C.Attributes.sqla_mapper.get_property('d').argument is D
+ C.append_field("d", D.store_as("table"))
+ assert C.Attributes.sqla_mapper.get_property("d").argument is D
def test_append_field_complex_delayed(self):
class C(TableModel):
@@ -1070,9 +1087,9 @@ class C(TableModel):
class D(C):
i = Integer32
- C.append_field('d', DateTime)
+ C.append_field("d", DateTime)
- assert D.Attributes.sqla_mapper.has_property('d')
+ assert D.Attributes.sqla_mapper.has_property("d")
def _test_append_field_complex_explicit_existing_column(self):
# FIXME: Test something!
@@ -1086,7 +1103,7 @@ class C(TableModel):
class D(TableModel):
__tablename__ = "d"
id = Integer32(pk=True)
- c = C.store_as('table')
+ c = C.store_as("table")
c_id = Integer32(15)
def test_append_field_complex_circular_array(self):
@@ -1097,10 +1114,10 @@ class C(TableModel):
class D(TableModel):
__tablename__ = "dd"
id = Integer32(pk=True)
- c = Array(C).customize(store_as=table(right='dd_id'))
+ c = Array(C).customize(store_as=table(right="dd_id"))
- C.append_field('d', D.customize(store_as=table(left='dd_id')))
- self.metadata.create_all()
+ C.append_field("d", D.customize(store_as=table(left="dd_id")))
+ self.metadata.create_all(self.engine)
c1, c2 = C(id=1), C(id=2)
d = D(id=1, c=[c1, c2])
@@ -1117,10 +1134,9 @@ class D(TableModel):
__tablename__ = "d"
id = Integer32(pk=True)
- C.append_field('d', D.store_as('table'))
- assert C.Attributes.sqla_mapper.get_property('d').argument is D
- assert isinstance(C.Attributes.sqla_table.c['d_id'].type,
- sqlalchemy.Integer)
+ C.append_field("d", D.store_as("table"))
+ assert C.Attributes.sqla_mapper.get_property("d").argument is D
+ assert isinstance(C.Attributes.sqla_table.c["d_id"].type, sqlalchemy.Integer)
def test_append_field_array(self):
class C(TableModel):
@@ -1131,11 +1147,10 @@ class D(TableModel):
__tablename__ = "d"
id = Integer32(pk=True)
- C.append_field('d', Array(D).store_as('table'))
- assert C.Attributes.sqla_mapper.get_property('d').argument is D
+ C.append_field("d", Array(D).store_as("table"))
+ assert C.Attributes.sqla_mapper.get_property("d").argument is D
print(repr(D.Attributes.sqla_table))
- assert isinstance(D.Attributes.sqla_table.c['c_id'].type,
- sqlalchemy.Integer)
+ assert isinstance(D.Attributes.sqla_table.c["c_id"].type, sqlalchemy.Integer)
def test_append_field_array_many(self):
class C(TableModel):
@@ -1146,11 +1161,11 @@ class D(TableModel):
__tablename__ = "d"
id = Integer32(pk=True)
- C.append_field('d', Array(D).store_as(table(multi='c_d')))
- assert C.Attributes.sqla_mapper.get_property('d').argument is D
- rel_table = C.Attributes.sqla_metadata.tables['c_d']
- assert 'c_id' in rel_table.c
- assert 'd_id' in rel_table.c
+ C.append_field("d", Array(D).store_as(table(multi="c_d")))
+ assert C.Attributes.sqla_mapper.get_property("d").argument is D
+ rel_table = C.Attributes.sqla_metadata.tables["c_d"]
+ assert "c_id" in rel_table.c
+ assert "d_id" in rel_table.c
def test_append_field_complex_cust(self):
class C(TableModel):
@@ -1160,13 +1175,16 @@ class C(TableModel):
class D(TableModel):
__tablename__ = "d"
id = Integer32(pk=True)
- c = Array(C).store_as('table')
-
- C.append_field('d', D.customize(
- nullable=False,
- store_as=table(left='d_id'),
- ))
- assert C.__table__.c['d_id'].nullable == False
+ c = Array(C).store_as("table")
+
+ C.append_field(
+ "d",
+ D.customize(
+ nullable=False,
+ store_as=table(left="d_id"),
+ ),
+ )
+ assert C.__table__.c["d_id"].nullable == False
def _test_append_field_cust(self):
class C(TableModel):
@@ -1179,21 +1197,21 @@ class C(TableModel):
C()
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
assert "s" in C2._type_info
assert "s" in C2.Attributes.sqla_mapper.columns
- self.session.add(C2(s='foo'))
+ self.session.add(C2(s="foo"))
self.session.commit()
- assert self.session.query(C).first().s == 'foo'
+ assert self.session.query(C).first().s == "foo"
def test_polymorphic_cust(self):
class C(TableModel):
__tablename__ = "c"
__mapper_args__ = {
- 'polymorphic_on': 't',
- 'polymorphic_identity': 1,
+ "polymorphic_on": "t",
+ "polymorphic_identity": 1,
}
id = Integer32(pk=True)
@@ -1201,7 +1219,7 @@ class C(TableModel):
class D(C):
__mapper_args__ = {
- 'polymorphic_identity': 2,
+ "polymorphic_identity": 2,
}
d = Unicode
@@ -1216,10 +1234,10 @@ class D(C):
def test_base_append_simple(self):
class B(TableModel):
- __tablename__ = 'b'
+ __tablename__ = "b"
__mapper_args__ = {
- 'polymorphic_on': 't',
- 'polymorphic_identity': 1,
+ "polymorphic_on": "t",
+ "polymorphic_identity": 1,
}
id = Integer32(pk=True)
@@ -1227,29 +1245,29 @@ class B(TableModel):
class C(B):
__mapper_args__ = {
- 'polymorphic_identity': 1,
+ "polymorphic_identity": 1,
}
s = Unicode
- B.append_field('i', Integer32)
+ B.append_field("i", Integer32)
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
self.session.add(C(s="foo", i=42))
self.session.commit()
c = self.session.query(C).first()
- assert c.s == 'foo'
+ assert c.s == "foo"
assert c.i == 42
assert c.t == 1
def test_base_append_complex(self):
class B(TableModel):
- __tablename__ = 'b'
+ __tablename__ = "b"
__mapper_args__ = {
- 'polymorphic_on': 't',
- 'polymorphic_identity': 1,
+ "polymorphic_on": "t",
+ "polymorphic_identity": 1,
}
id = Integer32(pk=True)
@@ -1257,18 +1275,18 @@ class B(TableModel):
class C(B):
__mapper_args__ = {
- 'polymorphic_identity': 1,
+ "polymorphic_identity": 1,
}
s = Unicode
class D(TableModel):
- __tablename__ = 'd'
+ __tablename__ = "d"
id = Integer32(pk=True)
i = M(Integer32)
- B.append_field('d', D.store_as('table'))
+ B.append_field("d", D.store_as("table"))
- self.metadata.create_all()
+ self.metadata.create_all(self.engine)
self.session.add(C(d=D(i=42)))
self.session.commit()
@@ -1285,18 +1303,18 @@ def setUp(self):
def test_enum(self):
table_name = "test_enum"
- enums = ('SUBSCRIBED', 'UNSUBSCRIBED', 'UNCONFIRMED')
+ enums = ("SUBSCRIBED", "UNSUBSCRIBED", "UNCONFIRMED")
class SomeClass(TableModel):
__tablename__ = table_name
id = Integer32(primary_key=True)
- e = Enum(*enums, type_name='status_choices')
+ e = Enum(*enums, type_name="status_choices")
t = self.metadata.tables[table_name]
- assert 'e' in t.c
+ assert "e" in t.c
assert tuple(t.c.e.type.enums) == enums
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/test/transport/test_msgpack.py b/spyne/test/transport/test_msgpack.py
index c94174a10..96a71c843 100644
--- a/spyne/test/transport/test_msgpack.py
+++ b/spyne/test/transport/test_msgpack.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,19 +17,19 @@
#
import msgpack
+from twisted.trial import unittest
from spyne import Application, Service, rpc
from spyne.model import Unicode
from spyne.protocol.msgpack import MessagePackDocument
-from twisted.trial import unittest
-
class TestMessagePackServer(unittest.TestCase):
- def gen_prot(self, app):
- from spyne.server.twisted.msgpack import TwistedMessagePackProtocol
- from twisted.test.proto_helpers import StringTransportWithDisconnection
+ def gen_prot(self, app):
+ from twisted.internet.testing import StringTransportWithDisconnection
+
from spyne.server.msgpack import MessagePackServerBase
+ from spyne.server.twisted.msgpack import TwistedMessagePackProtocol
prot = TwistedMessagePackProtocol(MessagePackServerBase(app))
transport = StringTransportWithDisconnection()
@@ -39,19 +38,23 @@ def gen_prot(self, app):
return prot
- def test_roundtrip(self):
+ def test_roundtrip(self):
v = "yaaay!"
+
class SomeService(Service):
@rpc(Unicode, _returns=Unicode)
def yay(ctx, u):
return u
- app = Application([SomeService], 'tns',
- in_protocol=MessagePackDocument(),
- out_protocol=MessagePackDocument())
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=MessagePackDocument(),
+ out_protocol=MessagePackDocument(),
+ )
prot = self.gen_prot(app)
- request = msgpack.packb({'yay': [v]})
+ request = msgpack.packb({"yay": [v]})
prot.dataReceived(msgpack.packb([1, request]))
val = prot.transport.value()
print(repr(val))
@@ -60,26 +63,32 @@ def yay(ctx, u):
self.assertEqual(val, [0, msgpack.packb(v)])
- def test_roundtrip_deferred(self):
+ def test_roundtrip_deferred(self):
from twisted.internet import reactor
from twisted.internet.task import deferLater
v = "yaaay!"
p_ctx = []
+
class SomeService(Service):
@rpc(Unicode, _returns=Unicode)
def yay(ctx, u):
def _cb():
return u
+
p_ctx.append(ctx)
return deferLater(reactor, 0.1, _cb)
- app = Application([SomeService], 'tns',
- in_protocol=MessagePackDocument(),
- out_protocol=MessagePackDocument())
+ app = Application(
+ [SomeService],
+ "tns",
+ in_protocol=MessagePackDocument(),
+ out_protocol=MessagePackDocument(),
+ )
prot = self.gen_prot(app)
- request = msgpack.packb({'yay': [v]})
+ request = msgpack.packb({"yay": [v]})
+
def _ccb(_):
val = prot.transport.value()
print(repr(val))
@@ -91,4 +100,3 @@ def _ccb(_):
prot.dataReceived(msgpack.packb([1, request]))
return p_ctx[0].out_object[0].addCallback(_ccb)
-
diff --git a/spyne/test/util/test_address.py b/spyne/test/util/test_address.py
index 04f8918cd..36fd11229 100755
--- a/spyne/test/util/test_address.py
+++ b/spyne/test/util/test_address.py
@@ -42,10 +42,9 @@
from unittest import TestCase
-
from spyne.util.address import set_address_parser_settings
-set_address_parser_settings(trusted_proxies=['177.139.233.100'])
+set_address_parser_settings(trusted_proxies=["177.139.233.100"])
from spyne.util.address import address_parser
@@ -54,265 +53,264 @@ class IPv4TestCase(TestCase):
"""IP address Test"""
def test_meta_none(self):
- request = {
- }
+ request = {}
ip = address_parser.get_real_ip(request)
self.assertIsNone(ip)
def test_http_x_forwarded_for_multiple(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139',
- 'HTTP_X_REAL_IP': '177.139.233.132',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139",
+ "HTTP_X_REAL_IP": "177.139.233.132",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "198.84.193.157")
def test_http_x_forwarded_for_multiple_left_most_ip(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
- 'HTTP_X_REAL_IP': '177.139.233.132',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139",
+ "HTTP_X_REAL_IP": "177.139.233.132",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "198.84.193.157")
def test_http_x_forwarded_for_multiple_right_most_ip(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
- 'HTTP_X_REAL_IP': '177.139.233.132',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139",
+ "HTTP_X_REAL_IP": "177.139.233.132",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request, right_most_proxy=True)
self.assertEqual(ip, "177.139.233.139")
def test_http_x_forwarded_for_multiple_right_most_ip_private(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
- 'HTTP_X_REAL_IP': '177.139.233.132',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139",
+ "HTTP_X_REAL_IP": "177.139.233.132",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request, right_most_proxy=True)
self.assertEqual(ip, "177.139.233.139")
def test_http_x_forwarded_for_multiple_bad_address(self):
request = {
- 'HTTP_X_FORWARDED_FOR': 'unknown, 192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139',
- 'HTTP_X_REAL_IP': '177.139.233.132',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "unknown, 192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139",
+ "HTTP_X_REAL_IP": "177.139.233.132",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "198.84.193.157")
def test_http_x_forwarded_for_singleton(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '177.139.233.139',
- 'HTTP_X_REAL_IP': '177.139.233.132',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "177.139.233.139",
+ "HTTP_X_REAL_IP": "177.139.233.132",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.139")
def test_http_x_forwarded_for_singleton_private_address(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '192.168.255.182',
- 'HTTP_X_REAL_IP': '177.139.233.132',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "192.168.255.182",
+ "HTTP_X_REAL_IP": "177.139.233.132",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.132")
def test_bad_http_x_forwarded_for_fallback_on_x_real_ip(self):
request = {
- 'HTTP_X_FORWARDED_FOR': 'unknown 177.139.233.139',
- 'HTTP_X_REAL_IP': '177.139.233.132',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "unknown 177.139.233.139",
+ "HTTP_X_REAL_IP": "177.139.233.132",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.132")
def test_empty_http_x_forwarded_for_fallback_on_x_real_ip(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '',
- 'HTTP_X_REAL_IP': '177.139.233.132',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "",
+ "HTTP_X_REAL_IP": "177.139.233.132",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.132")
def test_empty_http_x_forwarded_for_empty_x_real_ip_fallback_on_remote_addr(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '',
- 'HTTP_X_REAL_IP': '',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "",
+ "HTTP_X_REAL_IP": "",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.133")
def test_empty_http_x_forwarded_for_private_x_real_ip_fallback_on_remote_addr(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '',
- 'HTTP_X_REAL_IP': '192.168.255.182',
- 'REMOTE_ADDR': '177.139.233.133',
+ "HTTP_X_FORWARDED_FOR": "",
+ "HTTP_X_REAL_IP": "192.168.255.182",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.133")
def test_private_http_x_forward_for_ip_addr(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '127.0.0.1',
- 'HTTP_X_REAL_IP': '',
- 'REMOTE_ADDR': '',
+ "HTTP_X_FORWARDED_FOR": "127.0.0.1",
+ "HTTP_X_REAL_IP": "",
+ "REMOTE_ADDR": "",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, None)
def test_private_remote_addr_for_ip_addr(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '',
- 'REMOTE_ADDR': '127.0.0.1',
+ "HTTP_X_FORWARDED_FOR": "",
+ "REMOTE_ADDR": "127.0.0.1",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, None)
def test_missing_x_forwarded(self):
request = {
- 'REMOTE_ADDR': '177.139.233.133',
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.133")
def test_missing_x_forwarded_missing_real_ip(self):
request = {
- 'REMOTE_ADDR': '177.139.233.133',
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.133")
def test_best_matched_real_ip(self):
request = {
- 'HTTP_X_REAL_IP': '127.0.0.1',
- 'REMOTE_ADDR': '172.31.233.133',
+ "HTTP_X_REAL_IP": "127.0.0.1",
+ "REMOTE_ADDR": "172.31.233.133",
}
ip = address_parser.get_ip(request)
self.assertEqual(ip, "172.31.233.133")
def test_best_matched_private_ip(self):
request = {
- 'HTTP_X_REAL_IP': '127.0.0.1',
- 'REMOTE_ADDR': '192.31.233.133',
+ "HTTP_X_REAL_IP": "127.0.0.1",
+ "REMOTE_ADDR": "192.31.233.133",
}
ip = address_parser.get_ip(request)
self.assertEqual(ip, "192.31.233.133")
def test_best_matched_private_ip_2(self):
request = {
- 'HTTP_X_REAL_IP': '192.31.233.133',
- 'REMOTE_ADDR': '127.0.0.1',
+ "HTTP_X_REAL_IP": "192.31.233.133",
+ "REMOTE_ADDR": "127.0.0.1",
}
ip = address_parser.get_ip(request)
self.assertEqual(ip, "192.31.233.133")
def test_x_forwarded_for_multiple(self):
request = {
- 'X_FORWARDED_FOR': '192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "198.84.193.157")
def test_x_forwarded_for_multiple_left_most_ip(self):
request = {
- 'X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "198.84.193.157")
def test_x_forwarded_for_multiple_right_most_ip(self):
request = {
- 'X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request, right_most_proxy=True)
self.assertEqual(ip, "177.139.233.139")
def test_x_forwarded_for_multiple_right_most_ip_private(self):
request = {
- 'X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request, right_most_proxy=True)
self.assertEqual(ip, "177.139.233.139")
def test_x_forwarded_for_multiple_bad_address(self):
request = {
- 'X_FORWARDED_FOR': 'unknown, 192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "unknown, 192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "198.84.193.157")
def test_x_forwarded_for_singleton(self):
request = {
- 'X_FORWARDED_FOR': '177.139.233.139',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "177.139.233.139",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.139")
def test_x_forwarded_for_singleton_private_address(self):
request = {
- 'X_FORWARDED_FOR': '192.168.255.182',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "192.168.255.182",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.133")
def test_bad_x_forwarded_for_fallback_on_x_real_ip(self):
request = {
- 'X_FORWARDED_FOR': 'unknown 177.139.233.139',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "unknown 177.139.233.139",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.133")
def test_empty_x_forwarded_for_fallback_on_x_real_ip(self):
request = {
- 'X_FORWARDED_FOR': '',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.133")
def test_empty_x_forwarded_for_empty_x_real_ip_fallback_on_remote_addr(self):
request = {
- 'X_FORWARDED_FOR': '',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.133")
def test_empty_x_forwarded_for_private_x_real_ip_fallback_on_remote_addr(self):
request = {
- 'X_FORWARDED_FOR': '',
- 'REMOTE_ADDR': '177.139.233.133',
+ "X_FORWARDED_FOR": "",
+ "REMOTE_ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.133")
def test_private_x_forward_for_ip_addr(self):
request = {
- 'X_FORWARDED_FOR': '127.0.0.1',
- 'REMOTE_ADDR': '',
+ "X_FORWARDED_FOR": "127.0.0.1",
+ "REMOTE_ADDR": "",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, None)
def test_x_forwarded_for_singleton_hyphen_as_delimiter(self):
request = {
- 'X-FORWARDED-FOR': '177.139.233.139',
- 'REMOTE-ADDR': '177.139.233.133',
+ "X-FORWARDED-FOR": "177.139.233.139",
+ "REMOTE-ADDR": "177.139.233.133",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "177.139.233.139")
@@ -322,14 +320,13 @@ class IPv4TrustedProxiesTestCase(TestCase):
"""Trusted Proxies - IP address Test"""
def test_meta_none(self):
- request = {
- }
+ request = {}
ip = address_parser.get_trusted_ip(request)
self.assertIsNone(ip)
def test_http_x_forwarded_for_conf_settings(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.100',
+ "HTTP_X_FORWARDED_FOR": "198.84.193.157, 177.139.200.139, 177.139.233.100",
}
ip = address_parser.get_trusted_ip(request)
@@ -337,66 +334,70 @@ def test_http_x_forwarded_for_conf_settings(self):
def test_http_x_forwarded_for_no_proxy(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
+ "HTTP_X_FORWARDED_FOR": "198.84.193.157, 177.139.200.139, 177.139.233.139",
}
ip = address_parser.get_trusted_ip(request, trusted_proxies=[])
self.assertIsNone(ip)
def test_http_x_forwarded_for_single_proxy(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
+ "HTTP_X_FORWARDED_FOR": "198.84.193.157, 177.139.200.139, 177.139.233.139",
}
- ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233.139'])
+ ip = address_parser.get_trusted_ip(request, trusted_proxies=["177.139.233.139"])
self.assertEqual(ip, "198.84.193.157")
def test_http_x_forwarded_for_single_proxy_with_right_most(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '177.139.233.139, 177.139.200.139, 198.84.193.157',
+ "HTTP_X_FORWARDED_FOR": "177.139.233.139, 177.139.200.139, 198.84.193.157",
}
- ip = address_parser.get_trusted_ip(request, right_most_proxy=True, trusted_proxies=['177.139.233.139'])
+ ip = address_parser.get_trusted_ip(
+ request, right_most_proxy=True, trusted_proxies=["177.139.233.139"]
+ )
self.assertEqual(ip, "198.84.193.157")
def test_http_x_forwarded_for_multi_proxy(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
+ "HTTP_X_FORWARDED_FOR": "198.84.193.157, 177.139.200.139, 177.139.233.139",
}
- ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233.138', '177.139.233.139'])
+ ip = address_parser.get_trusted_ip(
+ request, trusted_proxies=["177.139.233.138", "177.139.233.139"]
+ )
self.assertEqual(ip, "198.84.193.157")
def test_http_x_forwarded_for_all_proxies_in_subnet(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
+ "HTTP_X_FORWARDED_FOR": "198.84.193.157, 177.139.200.139, 177.139.233.139",
}
- ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233'])
+ ip = address_parser.get_trusted_ip(request, trusted_proxies=["177.139.233"])
self.assertEqual(ip, "198.84.193.157")
def test_http_x_forwarded_for_all_proxies_in_subnet_2(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
+ "HTTP_X_FORWARDED_FOR": "198.84.193.157, 177.139.200.139, 177.139.233.139",
}
- ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139'])
+ ip = address_parser.get_trusted_ip(request, trusted_proxies=["177.139"])
self.assertEqual(ip, "198.84.193.157")
def test_x_forwarded_for_single_proxy(self):
request = {
- 'X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
+ "X_FORWARDED_FOR": "198.84.193.157, 177.139.200.139, 177.139.233.139",
}
- ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233.139'])
+ ip = address_parser.get_trusted_ip(request, trusted_proxies=["177.139.233.139"])
self.assertEqual(ip, "198.84.193.157")
def test_x_forwarded_for_single_proxy_hyphens(self):
request = {
- 'X-FORWARDED-FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
+ "X-FORWARDED-FOR": "198.84.193.157, 177.139.200.139, 177.139.233.139",
}
- ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233.139'])
+ ip = address_parser.get_trusted_ip(request, trusted_proxies=["177.139.233.139"])
self.assertEqual(ip, "198.84.193.157")
def test_http_x_forwarded_for_and_x_forward_for_single_proxy(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '198.84.193.156, 177.139.200.139, 177.139.233.139',
- 'X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
+ "HTTP_X_FORWARDED_FOR": "198.84.193.156, 177.139.200.139, 177.139.233.139",
+ "X_FORWARDED_FOR": "198.84.193.157, 177.139.200.139, 177.139.233.139",
}
- ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233.139'])
+ ip = address_parser.get_trusted_ip(request, trusted_proxies=["177.139.233.139"])
self.assertEqual(ip, "198.84.193.156")
@@ -405,217 +406,217 @@ class IPv6TestCase(TestCase):
def test_http_x_forwarded_for_multiple(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba',
- 'HTTP_X_REAL_IP': '74dc::02ba',
- 'REMOTE_ADDR': '74dc::02ba',
+ "HTTP_X_FORWARDED_FOR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba",
+ "HTTP_X_REAL_IP": "74dc::02ba",
+ "REMOTE_ADDR": "74dc::02ba",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "3ffe:1900:4545:3:200:f8ff:fe21:67cf")
def test_http_x_forwarded_for_multiple_bad_address(self):
request = {
- 'HTTP_X_FORWARDED_FOR': 'unknown, ::1/128, 74dc::02ba',
- 'HTTP_X_REAL_IP': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
- 'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "HTTP_X_FORWARDED_FOR": "unknown, ::1/128, 74dc::02ba",
+ "HTTP_X_REAL_IP": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
+ "REMOTE_ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_http_x_forwarded_for_singleton(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '74dc::02ba',
- 'HTTP_X_REAL_IP': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
- 'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "HTTP_X_FORWARDED_FOR": "74dc::02ba",
+ "HTTP_X_REAL_IP": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
+ "REMOTE_ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_http_x_forwarded_for_singleton_private_address(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '::1/128',
- 'HTTP_X_REAL_IP': '74dc::02ba',
- 'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "HTTP_X_FORWARDED_FOR": "::1/128",
+ "HTTP_X_REAL_IP": "74dc::02ba",
+ "REMOTE_ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_bad_http_x_forwarded_for_fallback_on_x_real_ip(self):
request = {
- 'HTTP_X_FORWARDED_FOR': 'unknown ::1/128',
- 'HTTP_X_REAL_IP': '74dc::02ba',
- 'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "HTTP_X_FORWARDED_FOR": "unknown ::1/128",
+ "HTTP_X_REAL_IP": "74dc::02ba",
+ "REMOTE_ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_empty_http_x_forwarded_for_fallback_on_x_real_ip(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '',
- 'HTTP_X_REAL_IP': '74dc::02ba',
- 'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "HTTP_X_FORWARDED_FOR": "",
+ "HTTP_X_REAL_IP": "74dc::02ba",
+ "REMOTE_ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_empty_http_x_forwarded_for_empty_x_real_ip_fallback_on_remote_addr(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '',
- 'HTTP_X_REAL_IP': '',
- 'REMOTE_ADDR': '74dc::02ba',
+ "HTTP_X_FORWARDED_FOR": "",
+ "HTTP_X_REAL_IP": "",
+ "REMOTE_ADDR": "74dc::02ba",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_empty_http_x_forwarded_for_private_x_real_ip_fallback_on_remote_addr(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '',
- 'HTTP_X_REAL_IP': '::1/128',
- 'REMOTE_ADDR': '74dc::02ba',
+ "HTTP_X_FORWARDED_FOR": "",
+ "HTTP_X_REAL_IP": "::1/128",
+ "REMOTE_ADDR": "74dc::02ba",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_private_http_x_forward_for_ip_addr(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '::1/128',
- 'HTTP_X_REAL_IP': '',
- 'REMOTE_ADDR': '',
+ "HTTP_X_FORWARDED_FOR": "::1/128",
+ "HTTP_X_REAL_IP": "",
+ "REMOTE_ADDR": "",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, None)
def test_private_real_ip_for_ip_addr(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '',
- 'HTTP_X_REAL_IP': '::1/128',
- 'REMOTE_ADDR': '',
+ "HTTP_X_FORWARDED_FOR": "",
+ "HTTP_X_REAL_IP": "::1/128",
+ "REMOTE_ADDR": "",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, None)
def test_private_remote_addr_for_ip_addr(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '',
- 'HTTP_X_REAL_IP': '',
- 'REMOTE_ADDR': '::1/128',
+ "HTTP_X_FORWARDED_FOR": "",
+ "HTTP_X_REAL_IP": "",
+ "REMOTE_ADDR": "::1/128",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, None)
def test_missing_x_forwarded(self):
request = {
- 'HTTP_X_REAL_IP': '74dc::02ba',
- 'REMOTE_ADDR': '74dc::02ba',
+ "HTTP_X_REAL_IP": "74dc::02ba",
+ "REMOTE_ADDR": "74dc::02ba",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_missing_x_forwarded_missing_real_ip(self):
request = {
- 'REMOTE_ADDR': '74dc::02ba',
+ "REMOTE_ADDR": "74dc::02ba",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_missing_x_forwarded_missing_real_ip_mix_case(self):
request = {
- 'REMOTE_ADDR': '74DC::02BA',
+ "REMOTE_ADDR": "74DC::02BA",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_private_remote_address(self):
request = {
- 'REMOTE_ADDR': 'fe80::02ba',
+ "REMOTE_ADDR": "fe80::02ba",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, None)
def test_best_matched_real_ip(self):
request = {
- 'HTTP_X_REAL_IP': '::1',
- 'REMOTE_ADDR': 'fe80::02ba',
+ "HTTP_X_REAL_IP": "::1",
+ "REMOTE_ADDR": "fe80::02ba",
}
ip = address_parser.get_ip(request)
self.assertEqual(ip, "fe80::02ba")
def test_x_forwarded_for_multiple(self):
request = {
- 'X_FORWARDED_FOR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba',
- 'REMOTE_ADDR': '74dc::02ba',
+ "X_FORWARDED_FOR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba",
+ "REMOTE_ADDR": "74dc::02ba",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "3ffe:1900:4545:3:200:f8ff:fe21:67cf")
def test_x_forwarded_for_multiple_bad_address(self):
request = {
- 'X_FORWARDED_FOR': 'unknown, ::1/128, 74dc::02ba',
- 'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "X_FORWARDED_FOR": "unknown, ::1/128, 74dc::02ba",
+ "REMOTE_ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_x_forwarded_for_singleton(self):
request = {
- 'X_FORWARDED_FOR': '74dc::02ba',
- 'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "X_FORWARDED_FOR": "74dc::02ba",
+ "REMOTE_ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_x_forwarded_for_singleton_private_address(self):
request = {
- 'X_FORWARDED_FOR': '::1/128',
- 'HTTP_X_REAL_IP': '74dc::02ba',
- 'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "X_FORWARDED_FOR": "::1/128",
+ "HTTP_X_REAL_IP": "74dc::02ba",
+ "REMOTE_ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_bad_x_forwarded_for_fallback_on_x_real_ip(self):
request = {
- 'X_FORWARDED_FOR': 'unknown ::1/128',
- 'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "X_FORWARDED_FOR": "unknown ::1/128",
+ "REMOTE_ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "3ffe:1900:4545:3:200:f8ff:fe21:67cf")
def test_empty_x_forwarded_for_fallback_on_x_real_ip(self):
request = {
- 'X_FORWARDED_FOR': '',
- 'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "X_FORWARDED_FOR": "",
+ "REMOTE_ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "3ffe:1900:4545:3:200:f8ff:fe21:67cf")
def test_empty_x_forwarded_for_empty_x_real_ip_fallback_on_remote_addr(self):
request = {
- 'X_FORWARDED_FOR': '',
- 'REMOTE_ADDR': '74dc::02ba',
+ "X_FORWARDED_FOR": "",
+ "REMOTE_ADDR": "74dc::02ba",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_empty_x_forwarded_for_private_x_real_ip_fallback_on_remote_addr(self):
request = {
- 'X_FORWARDED_FOR': '',
- 'REMOTE_ADDR': '74dc::02ba',
+ "X_FORWARDED_FOR": "",
+ "REMOTE_ADDR": "74dc::02ba",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
def test_private_x_forward_for_ip_addr(self):
request = {
- 'X_FORWARDED_FOR': '::1/128',
- 'REMOTE_ADDR': '',
+ "X_FORWARDED_FOR": "::1/128",
+ "REMOTE_ADDR": "",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, None)
def test_x_forwarded_for_singleton_hyphen_as_delimiter(self):
request = {
- 'X-FORWARDED-FOR': '74dc::02ba',
- 'REMOTE-ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
+ "X-FORWARDED-FOR": "74dc::02ba",
+ "REMOTE-ADDR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
}
ip = address_parser.get_real_ip(request)
self.assertEqual(ip, "74dc::02ba")
@@ -626,14 +627,14 @@ class IPv6TrustedProxiesTestCase(TestCase):
def test_http_x_forwarded_for_no_proxy(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba',
+ "HTTP_X_FORWARDED_FOR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba",
}
ip = address_parser.get_trusted_ip(request, trusted_proxies=[])
self.assertIsNone(ip)
def test_http_x_forwarded_for_single_proxy(self):
request = {
- 'HTTP_X_FORWARDED_FOR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba',
+ "HTTP_X_FORWARDED_FOR": "3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba",
}
- ip = address_parser.get_trusted_ip(request, trusted_proxies=['74dc::02ba'])
+ ip = address_parser.get_trusted_ip(request, trusted_proxies=["74dc::02ba"])
self.assertEqual(ip, "3ffe:1900:4545:3:200:f8ff:fe21:67cf")
diff --git a/spyne/test/util/test_util.py b/spyne/test/util/test_util.py
index 3b8b5e740..8f82566ff 100755
--- a/spyne/test/util/test_util.py
+++ b/spyne/test/util/test_util.py
@@ -2,88 +2,87 @@
from __future__ import print_function
-import json
import decimal
+import json
import unittest
+from datetime import datetime
+from decimal import Decimal as D
+from pprint import pprint
import pytz
import sqlalchemy
-
-from pprint import pprint
-from decimal import Decimal as D
-from datetime import datetime
-
from lxml import etree
+from spyne.application import Application
from spyne.const import MAX_STRING_FIELD_LENGTH
-
from spyne.decorator import srpc
-from spyne.application import Application
-
-from spyne.model.complex import XmlAttribute, TypeInfo
-from spyne.model.complex import ComplexModel
-from spyne.model.complex import Iterable
-from spyne.model.complex import Array
-from spyne.model.primitive import Decimal
-from spyne.model.primitive import DateTime
-from spyne.model.primitive import Integer
-from spyne.model.primitive import Unicode
-
+from spyne.model.complex import Array, ComplexModel, Iterable, TypeInfo, XmlAttribute
+from spyne.model.primitive import DateTime, Decimal, Integer, Unicode
from spyne.service import Service
-
-from spyne.util import AttrDict, AttrDictColl, get_version
-from spyne.util import memoize, memoize_ignore_none, memoize_ignore, memoize_id
-
+from spyne.util import (
+ AttrDict,
+ AttrDictColl,
+ get_version,
+ memoize,
+ memoize_id,
+ memoize_ignore,
+ memoize_ignore_none,
+)
+from spyne.util.dictdoc import (
+ get_dict_as_object,
+ get_object_as_dict,
+ get_object_as_json,
+ get_object_as_yaml,
+)
from spyne.util.protocol import deserialize_request_string
-
-from spyne.util.dictdoc import get_dict_as_object, get_object_as_yaml, \
- get_object_as_json
-from spyne.util.dictdoc import get_object_as_dict
from spyne.util.tdict import tdict
from spyne.util.tlist import tlist
-
-from spyne.util.xml import get_object_as_xml
-from spyne.util.xml import get_xml_as_object
-from spyne.util.xml import get_schema_documents
-from spyne.util.xml import get_validation_schema
+from spyne.util.xml import (
+ get_object_as_xml,
+ get_schema_documents,
+ get_validation_schema,
+ get_xml_as_object,
+)
class TestUtil(unittest.TestCase):
def test_version(self):
- assert get_version('sqlalchemy') == get_version(sqlalchemy)
- assert '.'.join([str(i) for i in get_version('sqlalchemy')]) == \
- sqlalchemy.__version__
+ assert get_version("sqlalchemy") == get_version(sqlalchemy)
+ assert (
+ ".".join([str(i) for i in get_version("sqlalchemy")])
+ == sqlalchemy.__version__
+ )
class TestTypeInfo(unittest.TestCase):
def test_insert(self):
d = TypeInfo()
- d['a'] = 1
- assert d[0] == d['a'] == 1
+ d["a"] = 1
+ assert d[0] == d["a"] == 1
- d.insert(0, ('b', 2))
+ d.insert(0, ("b", 2))
- assert d[1] == d['a'] == 1
- assert d[0] == d['b'] == 2
+ assert d[1] == d["a"] == 1
+ assert d[0] == d["b"] == 2
def test_insert_existing(self):
d = TypeInfo()
d["a"] = 1
d["b"] = 2
- assert d[1] == d['b'] == 2
+ assert d[1] == d["b"] == 2
- d.insert(0, ('b', 3))
- assert d[1] == d['a'] == 1
- assert d[0] == d['b'] == 3
+ d.insert(0, ("b", 3))
+ assert d[1] == d["a"] == 1
+ assert d[0] == d["b"] == 3
def test_update(self):
d = TypeInfo()
d["a"] = 1
- d.update([('b', 2)])
- assert d[0] == d['a'] == 1
- assert d[1] == d['b'] == 2
+ d.update([("b", 2)])
+ assert d[0] == d["a"] == 1
+ assert d[1] == d["b"] == 2
class TestXml(unittest.TestCase):
@@ -114,7 +113,7 @@ class C(ComplexModel):
def test_deserialize(self):
class Punk(ComplexModel):
- __namespace__ = 'some_namespace'
+ __namespace__ = "some_namespace"
a = Unicode
b = Integer
@@ -122,7 +121,7 @@ class Punk(ComplexModel):
d = DateTime
class Foo(ComplexModel):
- __namespace__ = 'some_other_namespace'
+ __namespace__ = "some_other_namespace"
a = Unicode
b = Integer
@@ -133,33 +132,38 @@ class Foo(ComplexModel):
def __eq__(self, other):
# remember that this is a test object
assert (
- self.a == other.a and
- self.b == other.b and
- self.c == other.c and
- self.d == other.d and
- self.e == other.e
+ self.a == other.a
+ and self.b == other.b
+ and self.c == other.c
+ and self.d == other.d
+ and self.e == other.e
)
return True
docs = get_schema_documents([Punk, Foo])
pprint(docs)
- assert docs['s0'].tag == '{http://www.w3.org/2001/XMLSchema}schema'
- assert docs['tns'].tag == '{http://www.w3.org/2001/XMLSchema}schema'
+ assert docs["s0"].tag == "{http://www.w3.org/2001/XMLSchema}schema"
+ assert docs["tns"].tag == "{http://www.w3.org/2001/XMLSchema}schema"
print()
- print("the other namespace %r:" % docs['tns'].attrib['targetNamespace'])
- assert docs['tns'].attrib['targetNamespace'] == 'some_namespace'
- print(etree.tostring(docs['tns'], pretty_print=True))
+ print("the other namespace %r:" % docs["tns"].attrib["targetNamespace"])
+ assert docs["tns"].attrib["targetNamespace"] == "some_namespace"
+ print(etree.tostring(docs["tns"], pretty_print=True))
print()
- print("the other namespace %r:" % docs['s0'].attrib['targetNamespace'])
- assert docs['s0'].attrib['targetNamespace'] == 'some_other_namespace'
- print(etree.tostring(docs['s0'], pretty_print=True))
+ print("the other namespace %r:" % docs["s0"].attrib["targetNamespace"])
+ assert docs["s0"].attrib["targetNamespace"] == "some_other_namespace"
+ print(etree.tostring(docs["s0"], pretty_print=True))
print()
- foo = Foo(a=u'a', b=1, c=decimal.Decimal('3.4'),
- d=datetime(2011,2,20,tzinfo=pytz.utc), e=5)
+ foo = Foo(
+ a="a",
+ b=1,
+ c=decimal.Decimal("3.4"),
+ d=datetime(2011, 2, 20, tzinfo=pytz.utc),
+ e=5,
+ )
doc = get_object_as_xml(foo, Foo)
print(etree.tostring(doc, pretty_print=True))
foo_back = get_xml_as_object(doc, Foo)
@@ -189,11 +193,11 @@ class F(E):
class C(object):
pass
- d = cdict({A: "fun", F: 'zan'})
+ d = cdict({A: "fun", F: "zan"})
- assert d[A] == 'fun'
- assert d[B] == 'fun'
- assert d[F] == 'zan'
+ assert d[A] == "fun"
+ assert d[B] == "fun"
+ assert d[F] == "zan"
try:
d[C]
except KeyError:
@@ -209,7 +213,7 @@ def test_tdict_notype(self):
assert d[0] == 1
d = tdict()
- d.update({0:1})
+ d.update({0: 1})
assert d[0] == 1
d = tdict.fromkeys([0], 1)
@@ -225,8 +229,8 @@ def test_tdict_k(self):
raise Exception("must fail")
d = tdict(str)
- d['s'] = 1
- assert d['s'] == 1
+ d["s"] = 1
+ assert d["s"] == 1
def test_tdict_v(self):
d = tdict(vt=str)
@@ -238,8 +242,8 @@ def test_tdict_v(self):
raise Exception("must fail")
d = tdict(vt=str)
- d[0] = 's'
- assert d[0] == 's'
+ d[0] = "s"
+ assert d[0] == "s"
class TestLogRepr(unittest.TestCase):
@@ -249,31 +253,32 @@ def test_log_repr_simple(self):
from spyne.util.web import log_repr
class Z(ComplexModel):
- z=String
+ z = String
l = MAX_STRING_FIELD_LENGTH + 100
print(log_repr(Z(z="a" * l)))
- print("Z(z='%s'(...))" % ('a' * MAX_STRING_FIELD_LENGTH))
+ print("Z(z='%s'(...))" % ("a" * MAX_STRING_FIELD_LENGTH))
- assert log_repr(Z(z="a" * l)) == "Z(z='%s'(...))" % \
- ('a' * MAX_STRING_FIELD_LENGTH)
- assert log_repr(['a','b','c'], Array(String)) == "['a', 'b', (...)]"
+ assert log_repr(Z(z="a" * l)) == "Z(z='%s'(...))" % (
+ "a" * MAX_STRING_FIELD_LENGTH
+ )
+ assert log_repr(["a", "b", "c"], Array(String)) == "['a', 'b', (...)]"
def test_log_repr_complex(self):
- from spyne.model import ByteArray
- from spyne.model import File
+ from spyne.model import ByteArray, File
from spyne.model.complex import ComplexModel
from spyne.model.primitive import String
from spyne.util.web import log_repr
class Z(ComplexModel):
_type_info = [
- ('f', File(logged=False)),
- ('t', ByteArray(logged=False)),
- ('z', Array(String)),
+ ("f", File(logged=False)),
+ ("t", ByteArray(logged=False)),
+ ("z", Array(String)),
]
+
l = MAX_STRING_FIELD_LENGTH + 100
- val = Z(z=["abc"] * l, t=['t'], f=File.Value(name='aaa', data=['t']))
+ val = Z(z=["abc"] * l, t=["t"], f=File.Value(name="aaa", data=["t"]))
print(repr(val))
assert log_repr(val) == "Z(z=['abc', 'abc', (...)])"
@@ -296,7 +301,7 @@ def test_log_repr_dict_keys(self):
from spyne.model import AnyDict
from spyne.util.web import log_repr
- t = AnyDict(logged='keys')
+ t = AnyDict(logged="keys")
assert log_repr({1: 1}, t) == "{1: (...)}"
@@ -306,7 +311,7 @@ def test_log_repr_dict_values(self):
from spyne.model import AnyDict
from spyne.util.web import log_repr
- t = AnyDict(logged='values')
+ t = AnyDict(logged="values")
assert log_repr({1: 1}, t) == "{(...): 1}"
@@ -316,7 +321,7 @@ def test_log_repr_dict_full(self):
from spyne.model import AnyDict
from spyne.util.web import log_repr
- t = AnyDict(logged='full')
+ t = AnyDict(logged="full")
assert log_repr({1: 1, 2: 2, 3: 3}, t) == "{1: 1, 2: 2, 3: 3}"
assert log_repr([1, 2, 3], t) == "[1, 2, 3]"
@@ -325,7 +330,7 @@ def test_log_repr_dict_keys_full(self):
from spyne.model import AnyDict
from spyne.util.web import log_repr
- t = AnyDict(logged='keys-full')
+ t = AnyDict(logged="keys-full")
assert log_repr({1: 1, 2: 2, 3: 3}, t) == "{1: (...), 2: (...), 3: (...)}"
assert log_repr([1, 2, 3], t) == "[1, 2, 3]"
@@ -334,7 +339,7 @@ def test_log_repr_dict_values_full(self):
from spyne.model import AnyDict
from spyne.util.web import log_repr
- t = AnyDict(logged='values-full')
+ t = AnyDict(logged="values-full")
assert log_repr({1: 1, 2: 2, 3: 3}, t) == "{(...): 1, (...): 2, (...): 3}"
assert log_repr([1, 2, 3], t) == "[1, 2, 3]"
@@ -349,8 +354,9 @@ class SomeService(Service):
def some_call(yo):
return range(yo)
- app = Application([SomeService], 'tns', in_protocol=Soap11(),
- out_protocol=Soap11())
+ app = Application(
+ [SomeService], "tns", in_protocol=Soap11(), out_protocol=Soap11()
+ )
meat = 30
@@ -375,36 +381,55 @@ class TestEtreeDict(unittest.TestCase):
def test_simple(self):
from lxml.etree import tostring
- from spyne.util.etreeconv import root_dict_to_etree
- assert tostring(root_dict_to_etree({'a':{'b':'c'}})) == b'c'
- def test_not_sized(self):
- from lxml.etree import tostring
from spyne.util.etreeconv import root_dict_to_etree
- complex_value = root_dict_to_etree({'a':{'b':1}})
- self.assertEqual(tostring(complex_value), b'1',
- "The integer should be properly rendered in the etree")
-
- complex_none = root_dict_to_etree({'a':{'b':None}})
- self.assertEqual(tostring(complex_none), b'',
- "None should not be rendered in the etree")
+ assert tostring(root_dict_to_etree({"a": {"b": "c"}})) == b"c"
- simple_value = root_dict_to_etree({'a': 1})
- self.assertEqual(tostring(simple_value), b'1',
- "The integer should be properly rendered in the etree")
-
- none_value = root_dict_to_etree({'a': None})
- self.assertEqual(tostring(none_value), b'',
- "None should not be rendered in the etree")
+ def test_not_sized(self):
+ from lxml.etree import tostring
- string_value = root_dict_to_etree({'a': 'lol'})
- self.assertEqual(tostring(string_value), b'lol',
- "A string should be rendered as a string")
+ from spyne.util.etreeconv import root_dict_to_etree
- complex_string_value = root_dict_to_etree({'a': {'b': 'lol'}})
- self.assertEqual(tostring(complex_string_value), b'lol',
- "A string should be rendered as a string")
+ complex_value = root_dict_to_etree({"a": {"b": 1}})
+ self.assertEqual(
+ tostring(complex_value),
+ b"1",
+ "The integer should be properly rendered in the etree",
+ )
+
+ complex_none = root_dict_to_etree({"a": {"b": None}})
+ self.assertEqual(
+ tostring(complex_none),
+ b"",
+ "None should not be rendered in the etree",
+ )
+
+ simple_value = root_dict_to_etree({"a": 1})
+ self.assertEqual(
+ tostring(simple_value),
+ b"1",
+ "The integer should be properly rendered in the etree",
+ )
+
+ none_value = root_dict_to_etree({"a": None})
+ self.assertEqual(
+ tostring(none_value), b"", "None should not be rendered in the etree"
+ )
+
+ string_value = root_dict_to_etree({"a": "lol"})
+ self.assertEqual(
+ tostring(string_value),
+ b"lol",
+ "A string should be rendered as a string",
+ )
+
+ complex_string_value = root_dict_to_etree({"a": {"b": "lol"}})
+ self.assertEqual(
+ tostring(complex_string_value),
+ b"lol",
+ "A string should be rendered as a string",
+ )
class TestDictDoc(unittest.TestCase):
@@ -417,15 +442,13 @@ class C(ComplexModel):
def __eq__(self, other):
print("Yaaay!")
- return self.i == other.i and \
- self.s == other.s and \
- self.a == other.a
+ return self.i == other.i and self.s == other.s and self.a == other.a
- c = C(i=5, s="x", a=[datetime(2011,12,22, tzinfo=pytz.utc)])
+ c = C(i=5, s="x", a=[datetime(2011, 12, 22, tzinfo=pytz.utc)])
- for iw, ca in ((False,dict), (True,dict), (False,list), (True, list)):
+ for iw, ca in ((False, dict), (True, dict), (False, list), (True, list)):
print()
- print('complex_as:', ca)
+ print("complex_as:", ca)
d = get_object_as_dict(c, C, complex_as=ca)
print(d)
o = get_dict_as_object(d, C, complex_as=ca)
@@ -436,12 +459,12 @@ def __eq__(self, other):
class TestAttrDict(unittest.TestCase):
def test_attr_dict(self):
- assert AttrDict(a=1)['a'] == 1
+ assert AttrDict(a=1)["a"] == 1
def test_attr_dict_coll(self):
- assert AttrDictColl('SomeDict').SomeDict.NAME == 'SomeDict'
- assert AttrDictColl('SomeDict').SomeDict(a=1)['a'] == 1
- assert AttrDictColl('SomeDict').SomeDict(a=1).NAME == 'SomeDict'
+ assert AttrDictColl("SomeDict").SomeDict.NAME == "SomeDict"
+ assert AttrDictColl("SomeDict").SomeDict(a=1)["a"] == 1
+ assert AttrDictColl("SomeDict").SomeDict(a=1).NAME == "SomeDict"
class TestYaml(unittest.TestCase):
@@ -450,7 +473,7 @@ class C(ComplexModel):
a = Unicode
b = Decimal
- ret = get_object_as_yaml(C(a='burak', b=D(30)), C)
+ ret = get_object_as_yaml(C(a="burak", b=D(30)), C)
assert ret == b"""C:
a: burak
b: '30'
@@ -461,15 +484,14 @@ class TestJson(unittest.TestCase):
def test_deser(self):
class C(ComplexModel):
_type_info = [
- ('a', Unicode),
- ('b', Decimal),
+ ("a", Unicode),
+ ("b", Decimal),
]
- ret = get_object_as_json(C(a='burak', b=D(30)), C)
+ ret = get_object_as_json(C(a="burak", b=D(30)), C)
assert ret == b'["burak", "30"]'
- ret = get_object_as_json(C(a='burak', b=D(30)), C, complex_as=dict)
- assert json.loads(ret.decode('utf8')) == \
- json.loads(u'{"a": "burak", "b": "30"}')
+ ret = get_object_as_json(C(a="burak", b=D(30)), C, complex_as=dict)
+ assert json.loads(ret.decode("utf8")) == json.loads('{"a": "burak", "b": "30"}')
class TestFifo(unittest.TestCase):
@@ -515,13 +537,13 @@ def test_tlist(self):
a[5:] = [5]
try:
- tlist([1, 2, 'a'], int)
- a.append('a')
- a += ['a']
- _ = ['a'] + a
- _ = a + ['a']
- a[0] = 'a'
- a[0:] = 'a'
+ tlist([1, 2, "a"], int)
+ a.append("a")
+ a += ["a"]
+ _ = ["a"] + a
+ _ = a + ["a"]
+ a[0] = "a"
+ a[0:] = "a"
except TypeError:
pass
@@ -532,6 +554,7 @@ def test_tlist(self):
class TestMemoization(unittest.TestCase):
def test_memoize(self):
counter = [0]
+
@memoize
def f(arg):
counter[0] += 1
@@ -546,6 +569,7 @@ def f(arg):
def test_memoize_ignore_none(self):
counter = [0]
+
@memoize_ignore_none
def f(arg):
counter[0] += 1
@@ -563,6 +587,7 @@ def f(arg):
def test_memoize_ignore_values(self):
counter = [0]
+
@memoize_ignore((1,))
def f(arg):
counter[0] += 1
@@ -580,6 +605,7 @@ def f(arg):
def test_memoize_id(self):
counter = [0]
+
@memoize_id
def f(arg):
counter[0] += 1
@@ -597,5 +623,5 @@ def f(arg):
assert counter[0] == 3
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main()
diff --git a/spyne/util/__init__.py b/spyne/util/__init__.py
index 794eb8898..1eeaa3818 100644
--- a/spyne/util/__init__.py
+++ b/spyne/util/__init__.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,40 +17,31 @@
#
import logging
-logger = logging.getLogger(__name__)
-
-from spyne.util import six
-
-from spyne.util.coopmt import keepfirst
-from spyne.util.coopmt import coroutine
-from spyne.util.coopmt import Break
-
-from spyne.util.memo import memoize
-from spyne.util.memo import memoize_first
-from spyne.util.memo import memoize_ignore
-from spyne.util.memo import memoize_ignore_none
-from spyne.util.memo import memoize_id
-from spyne.util.attrdict import AttrDict
-from spyne.util.attrdict import AttrDictColl
-from spyne.util.attrdict import DefaultAttrDict
-
-from spyne.util._base import utctime
-from spyne.util._base import get_version
+logger = logging.getLogger(__name__)
+from spyne.util._base import get_version, utctime
+from spyne.util.attrdict import AttrDict, AttrDictColl, DefaultAttrDict
+from spyne.util.coopmt import Break, coroutine, keepfirst
+from spyne.util.memo import (
+ memoize,
+ memoize_first,
+ memoize_id,
+ memoize_ignore,
+ memoize_ignore_none,
+)
try:
- import thread
+ from urllib import quote, splithost, splittype, urlencode
- from urllib import splittype, splithost, quote, urlencode
- from urllib2 import urlopen, Request, HTTPError
+ import thread
+ from urllib2 import HTTPError, Request, urlopen
-except ImportError: # Python 3
+except ImportError: # Python 3
import _thread as thread
-
- from urllib.parse import splittype, splithost, quote, urlencode
- from urllib.request import urlopen, Request
from urllib.error import HTTPError
+ from urllib.parse import quote, splithost, splittype, urlencode
+ from urllib.request import Request, urlopen
def split_url(url):
@@ -85,19 +75,15 @@ def sanitize_args(a):
return args, kwargs
-if six.PY2:
- def _bytes_join(val, joiner=''):
- return joiner.join(val)
-else:
- def _bytes_join(val, joiner=b''):
- if isinstance(val, six.binary_type):
- return val
- return joiner.join(val)
+def _bytes_join(val, joiner=b""):
+ if isinstance(val, bytes):
+ return val
+ return joiner.join(val)
def utf8(s):
if isinstance(s, bytes):
- return s.decode('utf8')
+ return s.decode("utf8")
if isinstance(s, list):
return [utf8(ss) for ss in s]
diff --git a/spyne/util/_base.py b/spyne/util/_base.py
index d23dea56f..aefd40385 100644
--- a/spyne/util/_base.py
+++ b/spyne/util/_base.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -17,10 +16,10 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
-from time import mktime
from datetime import datetime
+from time import mktime
-from spyne.util import memoize, six
+from spyne.util.memo import memoize
def utctime():
@@ -29,10 +28,10 @@ def utctime():
@memoize
def get_version(package):
- if isinstance(package, (six.text_type, six.binary_type)):
+ if isinstance(package, (str, bytes)):
package = __import__(package)
- verstr = getattr(package, '__version__')
+ verstr = getattr(package, "__version__")
retval = []
for f in verstr.split("."):
diff --git a/spyne/util/_twisted_ws.py b/spyne/util/_twisted_ws.py
index df7468ce8..d6b63041b 100644
--- a/spyne/util/_twisted_ws.py
+++ b/spyne/util/_twisted_ws.py
@@ -10,22 +10,25 @@
factory.
"""
-__all__ = ["WebSocketsResource", "IWebSocketsProtocol", "IWebSocketsResource",
- "WebSocketsProtocol", "WebSocketsProtocolWrapper"]
+__all__ = [
+ "WebSocketsResource",
+ "IWebSocketsProtocol",
+ "IWebSocketsResource",
+ "WebSocketsProtocol",
+ "WebSocketsProtocolWrapper",
+]
+from enum import IntEnum
from hashlib import sha1
from struct import pack, unpack
-from zope.interface import implementer, Interface, providedBy, directlyProvides
-
-from twisted.python import log
-from twisted.python.constants import Flags, FlagConstant
-from twisted.internet.protocol import Protocol
from twisted.internet.interfaces import IProtocol
+from twisted.internet.protocol import Protocol
+from twisted.python import log
from twisted.web.resource import IResource
from twisted.web.server import NOT_DONE_YET
-
+from zope.interface import Interface, directlyProvides, implementer, providedBy
class _WSException(Exception):
@@ -34,25 +37,23 @@ class _WSException(Exception):
"""
-
-class CONTROLS(Flags):
+class CONTROLS(IntEnum):
"""
Control frame specifiers.
"""
- CONTINUE = FlagConstant(0)
- TEXT = FlagConstant(1)
- BINARY = FlagConstant(2)
- CLOSE = FlagConstant(8)
- PING = FlagConstant(9)
- PONG = FlagConstant(10)
+ CONTINUE = 0
+ TEXT = 1
+ BINARY = 2
+ CLOSE = 8
+ PING = 9
+ PONG = 10
# The GUID for WebSockets, from RFC 6455.
_WS_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
-
def _makeAccept(key):
"""
Create an B{accept} response for a given key.
@@ -66,7 +67,6 @@ def _makeAccept(key):
return sha1("%s%s" % (key, _WS_GUID)).digest().encode("base64").strip()
-
def _mask(buf, key):
"""
Mask or unmask a buffer of bytes with a masking key.
@@ -87,7 +87,6 @@ def _mask(buf, key):
return "".join(buf)
-
def _makeFrame(buf, opcode, fin, mask=None):
"""
Make a frame.
@@ -110,10 +109,10 @@ def _makeFrame(buf, opcode, fin, mask=None):
else:
lengthMask = 0
- if bufferLength > 0xffff:
- length = "%s%s" % (chr(lengthMask | 0x7f), pack(">Q", bufferLength))
- elif bufferLength > 0x7d:
- length = "%s%s" % (chr(lengthMask | 0x7e), pack(">H", bufferLength))
+ if bufferLength > 0xFFFF:
+ length = "%s%s" % (chr(lengthMask | 0x7F), pack(">Q", bufferLength))
+ elif bufferLength > 0x7D:
+ length = "%s%s" % (chr(lengthMask | 0x7E), pack(">H", bufferLength))
else:
length = chr(lengthMask | bufferLength)
@@ -129,7 +128,6 @@ def _makeFrame(buf, opcode, fin, mask=None):
return frame
-
def _parseFrames(frameBuffer, needMask=True):
"""
Parse frames in a highly compliant manner.
@@ -158,9 +156,9 @@ def _parseFrames(frameBuffer, needMask=True):
# Get the opcode, and translate it to a local enum which we actually
# care about.
- opcode = header & 0xf
+ opcode = header & 0xF
try:
- opcode = CONTROLS.lookupByValue(opcode)
+ opcode = CONTROLS(opcode)
except ValueError:
raise _WSException("Unknown opcode %d in frame" % opcode)
@@ -173,27 +171,27 @@ def _parseFrames(frameBuffer, needMask=True):
# The client must mask the data sent
raise _WSException("Received data not masked")
- length &= 0x7f
+ length &= 0x7F
# The offset we'll be using to walk through the frame. We use this
# because the offset is variable depending on the length and mask.
offset = 2
# Extra length fields.
- if length == 0x7e:
+ if length == 0x7E:
if len(payload) - start < 4:
break
- length = payload[start + 2:start + 4]
+ length = payload[start + 2 : start + 4]
length = unpack(">H", length)[0]
offset += 2
- elif length == 0x7f:
+ elif length == 0x7F:
if len(payload) - start < 10:
break
# Protocol bug: The top bit of this long long *must* be cleared;
# that is, it is expected to be interpreted as signed.
- length = payload[start + 2:start + 10]
+ length = payload[start + 2 : start + 10]
length = unpack(">Q", length)[0]
offset += 8
@@ -203,13 +201,13 @@ def _parseFrames(frameBuffer, needMask=True):
# that we don't create an invalid key.
break
- key = payload[start + offset:start + offset + 4]
+ key = payload[start + offset : start + offset + 4]
offset += 4
if len(payload) - (start + offset) < length:
break
- data = payload[start + offset:start + offset + length]
+ data = payload[start + offset : start + offset + length]
if masked:
data = _mask(data, key)
@@ -231,8 +229,6 @@ def _parseFrames(frameBuffer, needMask=True):
frameBuffer[:] = []
-
-
class IWebSocketsProtocol(IProtocol):
"""
A protocol which understands the WebSockets interface.
@@ -245,29 +241,26 @@ def sendFrame(opcode, data, fin):
Send a frame.
"""
-
def frameReceived(opcode, data, fin):
"""
Callback when a frame is received.
"""
-
def loseConnection():
"""
Close the connection sending a close frame first.
"""
-
@implementer(IWebSocketsProtocol)
class WebSocketsProtocol(Protocol):
"""
@since: 13.1
"""
+
_disconnecting = False
_buffer = None
-
def connectionMade(self):
"""
Log the new connection and initialize the buffer list.
@@ -275,7 +268,6 @@ def connectionMade(self):
log.msg("Opening connection with %s" % self.transport.getPeer())
self._buffer = []
-
def _parseFrames(self):
"""
Find frames in incoming data and pass them to the underlying protocol.
@@ -300,14 +292,12 @@ def _parseFrames(self):
# provoking PING.
self.transport.write(_makeFrame(data, CONTROLS.PONG, True))
-
def frameReceived(self, opcode, data, fin):
"""
Callback to implement.
"""
raise NotImplementedError()
-
def sendFrame(self, opcode, data, fin):
"""
Build a frame packet and send it over the wire.
@@ -315,7 +305,6 @@ def sendFrame(self, opcode, data, fin):
packet = _makeFrame(data, opcode, fin)
self.transport.write(packet)
-
def dataReceived(self, data):
"""
Append the data to the buffer list and parse the whole.
@@ -328,7 +317,6 @@ def dataReceived(self, data):
log.err()
self.transport.loseConnection()
-
def loseConnection(self):
"""
Close the connection.
@@ -349,7 +337,6 @@ def loseConnection(self):
self.transport.loseConnection()
-
class WebSocketsProtocolWrapper(WebSocketsProtocol):
"""
A protocol wrapper which provides L{IWebSocketsProtocol} by making messages
@@ -362,7 +349,6 @@ def __init__(self, wrappedProtocol, defaultOpcode=CONTROLS.TEXT):
self.wrappedProtocol = wrappedProtocol
self.defaultOpcode = defaultOpcode
-
def makeConnection(self, transport):
"""
Upon connection, provides the transport interface, and forwards ourself
@@ -372,7 +358,6 @@ def makeConnection(self, transport):
WebSocketsProtocol.makeConnection(self, transport)
self.wrappedProtocol.makeConnection(self)
-
def connectionMade(self):
"""
Initialize the list of messages.
@@ -380,14 +365,12 @@ def connectionMade(self):
WebSocketsProtocol.connectionMade(self)
self._messages = []
-
def write(self, data):
"""
Write to the websocket protocol, transforming C{data} in a frame.
"""
self.sendFrame(self.defaultOpcode, data, True)
-
def writeSequence(self, data):
"""
Send all chunks from C{data} using C{write}.
@@ -395,14 +378,12 @@ def writeSequence(self, data):
for chunk in data:
self.write(chunk)
-
def __getattr__(self, name):
"""
Forward all non-local attributes and methods to C{self.transport}.
"""
return getattr(self.transport, name)
-
def frameReceived(self, opcode, data, fin):
"""
FOr each frame received, accumulate the data (ignoring the opcode), and
@@ -414,7 +395,6 @@ def frameReceived(self, opcode, data, fin):
self._messages[:] = []
self.wrappedProtocol.dataReceived(content)
-
def connectionLost(self, reason):
"""
Forward C{connectionLost} to C{self.wrappedProtocol}.
@@ -422,7 +402,6 @@ def connectionLost(self, reason):
self.wrappedProtocol.connectionLost(reason)
-
class IWebSocketsResource(Interface):
"""
A WebSockets resource.
@@ -450,7 +429,6 @@ def lookupProtocol(protocolNames, request):
"""
-
@implementer(IResource, IWebSocketsResource)
class WebSocketsResource(object):
"""
@@ -469,21 +447,19 @@ class WebSocketsResource(object):
@since: 13.1
"""
+
isLeaf = True
def __init__(self, factory):
self._factory = factory
-
def getChildWithDefault(self, name, request):
"""
Reject attempts to retrieve a child resource. All path segments beyond
the one which refers to this resource are handled by the WebSocket
connection.
"""
- raise RuntimeError(
- "Cannot get IResource children from WebSocketsResource")
-
+ raise RuntimeError("Cannot get IResource children from WebSocketsResource")
def putChild(self, path, child):
"""
@@ -491,9 +467,7 @@ def putChild(self, path, child):
WebSocket connection handles all path segments beneath this resource,
so L{IResource} children can never be found.
"""
- raise RuntimeError(
- "Cannot put IResource children under WebSocketsResource")
-
+ raise RuntimeError("Cannot put IResource children under WebSocketsResource")
def lookupProtocol(self, protocolNames, request):
"""
@@ -513,7 +487,6 @@ def lookupProtocol(self, protocolNames, request):
protocol = self._factory.buildProtocol(request.transport.getPeer())
return protocol, None
-
def render(self, request):
"""
Render a request.
@@ -533,7 +506,7 @@ def render(self, request):
if request.method != "GET":
# 4.2.1.1 GET is required.
failed = True
- print('request.method', request.method)
+ print("request.method", request.method)
upgrade = request.getHeader("Upgrade")
if upgrade is None or "websocket" not in upgrade.lower():
@@ -551,7 +524,10 @@ def render(self, request):
if key is None:
# 4.2.1.5 The challenge key is required.
failed = True
- print('request.getHeader("Sec-WebSocket-Key")', request.getHeader("Sec-WebSocket-Key"))
+ print(
+ 'request.getHeader("Sec-WebSocket-Key")',
+ request.getHeader("Sec-WebSocket-Key"),
+ )
version = request.getHeader("Sec-WebSocket-Version")
if version != "13":
@@ -559,14 +535,16 @@ def render(self, request):
failed = True
# 4.4 Forward-compatible version checking.
request.setHeader("Sec-WebSocket-Version", "13")
- print('request.getHeader("Sec-WebSocket-Version")', request.getHeader("Sec-WebSocket-Version"))
+ print(
+ 'request.getHeader("Sec-WebSocket-Version")',
+ request.getHeader("Sec-WebSocket-Version"),
+ )
if failed:
request.setResponseCode(400)
return ""
- askedProtocols = request.requestHeaders.getRawHeaders(
- "Sec-WebSocket-Protocol")
+ askedProtocols = request.requestHeaders.getRawHeaders("Sec-WebSocket-Protocol")
protocol, protocolName = self.lookupProtocol(askedProtocols, request)
# If a protocol is not created, we deliver an error status.
diff --git a/spyne/util/address.py b/spyne/util/address.py
index 55a0da0bc..457bed75e 100644
--- a/spyne/util/address.py
+++ b/spyne/util/address.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -42,10 +41,11 @@
from __future__ import print_function
+import socket
+
# Direct plagiarization of https://github.com/un33k/django-ipware/
# at 57897c03026913892e61a164bc8b022778802ab9
-import socket
# List of known proxy server(s)
TRUSTED_PROXIES = []
@@ -53,16 +53,17 @@
# Search for the real IP address in the following order
# Configurable via settings.py
PRECEDENCE = (
- 'HTTP_X_FORWARDED_FOR', 'X_FORWARDED_FOR',
+ "HTTP_X_FORWARDED_FOR",
+ "X_FORWARDED_FOR",
# (client, proxy1, proxy2) OR (proxy2, proxy1, client)
- 'HTTP_CLIENT_IP',
- 'HTTP_X_REAL_IP',
- 'HTTP_X_FORWARDED',
- 'HTTP_X_CLUSTER_CLIENT_IP',
- 'HTTP_FORWARDED_FOR',
- 'HTTP_FORWARDED',
- 'HTTP_VIA',
- 'REMOTE_ADDR',
+ "HTTP_CLIENT_IP",
+ "HTTP_X_REAL_IP",
+ "HTTP_X_FORWARDED",
+ "HTTP_X_CLUSTER_CLIENT_IP",
+ "HTTP_FORWARDED_FOR",
+ "HTTP_FORWARDED",
+ "HTTP_VIA",
+ "REMOTE_ADDR",
)
# Private IP addresses
@@ -72,36 +73,51 @@
# Regex would be ideal here, but this is keeping it simple
# as fields are configurable via settings.py
PRIVATE_IP_PREFIXES = (
- '0.', # externally non-routable
- '10.', # class A private block
- '169.254.', # link-local block
- '172.16.', '172.17.', '172.18.', '172.19.',
- '172.20.', '172.21.', '172.22.', '172.23.',
- '172.24.', '172.25.', '172.26.', '172.27.',
- '172.28.', '172.29.', '172.30.', '172.31.',
+ "0.", # externally non-routable
+ "10.", # class A private block
+ "169.254.", # link-local block
+ "172.16.",
+ "172.17.",
+ "172.18.",
+ "172.19.",
+ "172.20.",
+ "172.21.",
+ "172.22.",
+ "172.23.",
+ "172.24.",
+ "172.25.",
+ "172.26.",
+ "172.27.",
+ "172.28.",
+ "172.29.",
+ "172.30.",
+ "172.31.",
# class B private blocks
- '192.0.2.',
+ "192.0.2.",
# reserved for documentation and example code
- '192.168.', # class C private block
- '255.255.255.', # IPv4 broadcast address
+ "192.168.", # class C private block
+ "255.255.255.", # IPv4 broadcast address
) + (
- '2001:db8:',
+ "2001:db8:",
# reserved for documentation and example code
- 'fc00:', # IPv6 private block
- 'fe80:', # link-local unicast
- 'ff00:', # IPv6 multicast
+ "fc00:", # IPv6 private block
+ "fe80:", # link-local unicast
+ "ff00:", # IPv6 multicast
)
LOOPBACK_PREFIX = (
- '127.', # IPv4 loopback device
- '::1', # IPv6 loopback device
+ "127.", # IPv4 loopback device
+ "::1", # IPv6 loopback device
)
NON_PUBLIC_IP_PREFIXES = PRIVATE_IP_PREFIXES + LOOPBACK_PREFIX
-def set_address_parser_settings(trusted_proxies, field_precedence=PRECEDENCE,
- private_ip_prefixes=NON_PUBLIC_IP_PREFIXES):
+def set_address_parser_settings(
+ trusted_proxies,
+ field_precedence=PRECEDENCE,
+ private_ip_prefixes=NON_PUBLIC_IP_PREFIXES,
+):
"""Changes global parameters for Spyne's residend ip address parser.
:param trusted_proxies: Tuple of reverse proxies that are under YOUR control.
@@ -113,30 +129,32 @@ def set_address_parser_settings(trusted_proxies, field_precedence=PRECEDENCE,
global address_parser
- address_parser = AddressParser(trusted_proxies=trusted_proxies,
- field_precedence=field_precedence,
- private_ip_prefixes=private_ip_prefixes)
+ address_parser = AddressParser(
+ trusted_proxies=trusted_proxies,
+ field_precedence=field_precedence,
+ private_ip_prefixes=private_ip_prefixes,
+ )
class AddressParser(object):
- def __init__(self, private_ip_prefixes=None, trusted_proxies=(),
- field_precedence=PRECEDENCE):
+ def __init__(
+ self, private_ip_prefixes=None, trusted_proxies=(), field_precedence=PRECEDENCE
+ ):
if private_ip_prefixes is not None:
self.private_ip_prefixes = private_ip_prefixes
else:
- self.private_ip_prefixes = \
- tuple([ip.lower() for ip in NON_PUBLIC_IP_PREFIXES])
+ self.private_ip_prefixes = tuple(
+ [ip.lower() for ip in NON_PUBLIC_IP_PREFIXES]
+ )
if len(trusted_proxies) > 0:
self.trusted_proxies = trusted_proxies
else:
- self.trusted_proxies = \
- tuple([ip.lower() for ip in TRUSTED_PROXIES])
+ self.trusted_proxies = tuple([ip.lower() for ip in TRUSTED_PROXIES])
self.field_precedence = field_precedence
-
def get_port(self, wsgi_env):
return wsgi_env.get("REMOTE_PORT", 0)
@@ -149,19 +167,22 @@ def get_ip(self, wsgi_env, real_ip_only=False, right_most_proxy=False):
for key in self.field_precedence:
value = wsgi_env.get(key, None)
if value is None:
- value = wsgi_env.get(key.replace('_', '-'), None)
+ value = wsgi_env.get(key.replace("_", "-"), None)
- if value is None or value == '':
+ if value is None or value == "":
continue
- ips = [ip.strip().lower() for ip in value.split(',')]
+ ips = [ip.strip().lower() for ip in value.split(",")]
if right_most_proxy and len(ips) > 1:
ips = reversed(ips)
for ip_str in ips:
- if ip_str is None or ip_str == '' or not \
- AddressParser.is_valid_ip(ip_str):
+ if (
+ ip_str is None
+ or ip_str == ""
+ or not AddressParser.is_valid_ip(ip_str)
+ ):
continue
if not ip_str.startswith(self.private_ip_prefixes):
@@ -173,8 +194,9 @@ def get_ip(self, wsgi_env, real_ip_only=False, right_most_proxy=False):
if best_matched_ip is None:
best_matched_ip = ip_str
- elif best_matched_ip.startswith(loopback) \
- and not ip_str.startswith(loopback):
+ elif best_matched_ip.startswith(loopback) and not ip_str.startswith(
+ loopback
+ ):
best_matched_ip = ip_str
return best_matched_ip
@@ -184,11 +206,11 @@ def get_real_ip(self, wsgi_env, right_most_proxy=False):
Returns client's best-matched `real` `externally-routable` ip-address,
or None
"""
- return self.get_ip(wsgi_env, real_ip_only=True,
- right_most_proxy=right_most_proxy)
+ return self.get_ip(
+ wsgi_env, real_ip_only=True, right_most_proxy=right_most_proxy
+ )
- def get_trusted_ip(self, wsgi_env, right_most_proxy=False,
- trusted_proxies=None):
+ def get_trusted_ip(self, wsgi_env, right_most_proxy=False, trusted_proxies=None):
"""
Returns client's ip-address from `trusted` proxy server(s) or None
"""
@@ -202,17 +224,17 @@ def get_trusted_ip(self, wsgi_env, right_most_proxy=False,
if trusted_proxies is None or len(trusted_proxies) == 0:
return
- meta_keys = ['HTTP_X_FORWARDED_FOR', 'X_FORWARDED_FOR']
+ meta_keys = ["HTTP_X_FORWARDED_FOR", "X_FORWARDED_FOR"]
for key in meta_keys:
value = wsgi_env.get(key, None)
if value is None:
- value = wsgi_env.get(key.replace('_', '-'), None)
+ value = wsgi_env.get(key.replace("_", "-"), None)
- if value is None or value == '':
+ if value is None or value == "":
continue
- ips = [ip.strip().lower() for ip in value.split(',')]
+ ips = [ip.strip().lower() for ip in value.split(",")]
if len(ips) > 1:
if right_most_proxy:
@@ -239,7 +261,7 @@ def is_valid_ipv4(ip_str):
socket.inet_aton(ip_str)
except (AttributeError, socket.error):
return False
- return ip_str.count('.') == 3
+ return ip_str.count(".") == 3
except socket.error:
return False
@@ -269,8 +291,9 @@ def is_valid_ip(ip_str):
Check the validity of an IP address
"""
- return AddressParser.is_valid_ipv4(ip_str) or \
- AddressParser.is_valid_ipv6(ip_str)
+ return AddressParser.is_valid_ipv4(ip_str) or AddressParser.is_valid_ipv6(
+ ip_str
+ )
address_parser = AddressParser()
diff --git a/spyne/util/appreg.py b/spyne/util/appreg.py
index 31c863798..baa8ad373 100644
--- a/spyne/util/appreg.py
+++ b/spyne/util/appreg.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -22,6 +21,7 @@
"""
import logging
+
logger = logging.getLogger(__name__)
applications = {}
@@ -29,10 +29,12 @@
try:
from collections import namedtuple
- _ApplicationMetaData = namedtuple("_ApplicationMetaData",
- ['app', 'inst_stack', 'null', 'ostr'])
+ _ApplicationMetaData = namedtuple(
+ "_ApplicationMetaData", ["app", "inst_stack", "null", "ostr"]
+ )
+
+except ImportError: # python 2.5
-except ImportError: # python 2.5
class _ApplicationMetaData:
def __init__(self, app, inst_stack, null, ostr):
self.app = app
@@ -53,6 +55,7 @@ def register_application(app):
try:
import traceback
+
stack = traceback.format_stack()
except ImportError:
stack = None
@@ -61,8 +64,10 @@ def register_application(app):
if prev is not None:
if hash(prev.app) == hash(app):
- logger.debug("Application %r previously registered as %r is the same"
- " as %r. Skipping." % (prev.app, key, app))
+ logger.debug(
+ "Application %r previously registered as %r is the same"
+ " as %r. Skipping." % (prev.app, key, app)
+ )
prev.inst_stack.append(stack)
else:
@@ -72,17 +77,21 @@ def register_application(app):
stack_traces = []
for s in prev.inst_stack:
if s is not None:
- stack_traces.append(''.join(s))
- logger.debug("Stack trace of the instantiation:\n%s" %
- '====================\n'.join(stack_traces))
-
- applications[key] = _ApplicationMetaData(app=app, inst_stack=[stack],
- null=NullServer(app, appinit=False),
- ostr=NullServer(app, appinit=False, ostr=True)
+ stack_traces.append("".join(s))
+ logger.debug(
+ "Stack trace of the instantiation:\n%s"
+ % "====================\n".join(stack_traces)
+ )
+
+ applications[key] = _ApplicationMetaData(
+ app=app,
+ inst_stack=[stack],
+ null=NullServer(app, appinit=False),
+ ostr=NullServer(app, appinit=False, ostr=True),
)
logger.debug("Registering %r as %r" % (app, key))
-def get_application(tns, name='Application'):
+def get_application(tns, name="Application"):
return applications.get((tns, name), None)
diff --git a/spyne/util/attrdict.py b/spyne/util/attrdict.py
index de996aaaf..cab216ebd 100644
--- a/spyne/util/attrdict.py
+++ b/spyne/util/attrdict.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -25,14 +24,14 @@ def __init__(self, *args, **kwargs):
def __call__(self, **kwargs):
retval = AttrDict(self.__data.items())
- for k,v in kwargs.items():
+ for k, v in kwargs.items():
setattr(retval, k, v)
return retval
def __setattr__(self, key, value):
if key == "_AttrDict__data":
return object.__setattr__(self, key, value)
- if key == 'items':
+ if key == "items":
raise ValueError("'items' is part of dict interface")
self.__data[key] = value
@@ -52,23 +51,32 @@ def update(self, d):
return self.__data.update(d)
def __repr__(self):
- return "AttrDict(%s)" % ', '.join(['%s=%r' % (k, v)
- for k,v in sorted(self.__data.items(), key=lambda x:x[0])])
+ return "AttrDict(%s)" % ", ".join(
+ [
+ "%s=%r" % (k, v)
+ for k, v in sorted(self.__data.items(), key=lambda x: x[0])
+ ]
+ )
if default is None:
+
def __getattr__(self, key):
return self.__data[key]
+
def __getitem__(self, key):
return self.__data[key]
+
else:
+
def __getitem__(self, key):
if key in self.__data:
return self.__data[key]
else:
return default()
+
def __getattr__(self, key):
- if key in ("_AttrDict__data", 'items', 'get', 'update'):
- return object.__getattribute__(self, '__data')
+ if key in ("_AttrDict__data", "items", "get", "update"):
+ return object.__getattribute__(self, "__data")
if key in self.__data:
return self.__data[key]
else:
@@ -76,12 +84,14 @@ def __getattr__(self, key):
return AttrDict
+
AttrDict = TAttrDict()
DefaultAttrDict = TAttrDict(lambda: None)
class AttrDictColl(object):
AttrDictImpl = DefaultAttrDict
+
def __init__(self, *args):
for a in args:
setattr(self, a, AttrDictColl.AttrDictImpl(NAME=a))
diff --git a/spyne/util/autorel.py b/spyne/util/autorel.py
index 2fc685ac8..b23a7a44b 100644
--- a/spyne/util/autorel.py
+++ b/spyne/util/autorel.py
@@ -47,9 +47,12 @@
#
import logging
+
logger = logging.getLogger(__name__)
-import os, re, sys
+import os
+import re
+import sys
from spyne.util.color import YEL
@@ -77,12 +80,11 @@
MAX_FILES = 0
else:
try:
- MAX_FILES = os.sysconf('SC_OPEN_MAX')
+ MAX_FILES = os.sysconf("SC_OPEN_MAX")
except AttributeError:
MAX_FILES = 1024
-
class AutoReloader(object):
"""Monitor which re-executes the process when files change.
@@ -103,7 +105,7 @@ class AutoReloader(object):
FILES = set()
"""The set of files to poll for modifications."""
- def __init__(self, frequency=1, match='.*'):
+ def __init__(self, frequency=1, match=".*"):
self.max_cloexec_files = MAX_FILES
self.mtimes = {}
@@ -125,29 +127,25 @@ def start(self):
retval = LoopingCall(self.run)
retval.start(self.frequency)
- return retval # oh no
+ return retval # oh no
def sysfiles(self):
"""Return a Set of sys.modules filenames to monitor."""
files = set()
for k, m in list(sys.modules.items()):
if re.match(self.match, k):
- if (
- hasattr(m, '__loader__') and
- hasattr(m.__loader__, 'archive')
- ):
+ if hasattr(m, "__loader__") and hasattr(m.__loader__, "archive"):
f = m.__loader__.archive
else:
try:
- f = getattr(m, '__file__', None)
+ f = getattr(m, "__file__", None)
except ImportError:
f = None
if f is not None and not os.path.isabs(f):
# ensure absolute paths so a os.chdir() in the app
# doesn't break me
- f = os.path.normpath(
- os.path.join(_module__file__base, f))
+ f = os.path.normpath(os.path.join(_module__file__base, f))
files.add(f)
return files
@@ -155,7 +153,7 @@ def run(self):
"""Reload the process if registered files have been modified."""
for filename in self.sysfiles() | self.files:
if filename:
- if filename.endswith('.pyc'):
+ if filename.endswith(".pyc"):
filename = filename[:-1]
oldtime = self.mtimes.get(filename, 0)
@@ -175,10 +173,10 @@ def run(self):
else:
if mtime is None or mtime > oldtime:
# The file has been deleted or modified.
- logger.info("Restarting because '%s' has changed." %
- filename)
+ logger.info("Restarting because '%s' has changed." % filename)
from twisted.internet import reactor
+
reactor.stop()
self._do_execv()
return
@@ -198,12 +196,9 @@ def _extend_pythonpath(env):
(This idea filched from tornado.autoreload)
"""
- path_prefix = '.' + os.pathsep
- existing_path = env.get('PYTHONPATH', '')
- needs_patch = (
- sys.path[0] == '' and
- not existing_path.startswith(path_prefix)
- )
+ path_prefix = "." + os.pathsep
+ existing_path = env.get("PYTHONPATH", "")
+ needs_patch = sys.path[0] == "" and not existing_path.startswith(path_prefix)
if needs_patch:
env["PYTHONPATH"] = path_prefix + existing_path
@@ -236,17 +231,18 @@ def _do_execv(self):
self._extend_pythonpath(os.environ)
- logger.info('Re-spawning %s' % ' '.join(args))
+ logger.info("Re-spawning %s" % " ".join(args))
logger.info("")
logger.info("%s Bye! %s", YEL("-" * 35), YEL("-" * 35))
logger.info("")
- if sys.platform[:4] == 'java':
+ if sys.platform[:4] == "java":
from _systemrestart import SystemRestart
+
raise SystemRestart
args.insert(0, sys.executable)
- if sys.platform == 'win32':
+ if sys.platform == "win32":
args = ['"%s"' % arg for arg in args]
os.chdir(_module__file__base)
diff --git a/spyne/util/cdict.py b/spyne/util/cdict.py
index 8e4d170c5..503c1a85a 100644
--- a/spyne/util/cdict.py
+++ b/spyne/util/cdict.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -55,15 +54,17 @@
"""
import logging
+
logger = logging.getLogger(__name__)
+
class cdict(dict):
def __getitem__(self, cls):
try:
return dict.__getitem__(self, cls)
except KeyError as e:
- if not hasattr(cls, '__bases__'):
+ if not hasattr(cls, "__bases__"):
cls = cls.__class__
for b in reversed(cls.__bases__):
diff --git a/spyne/util/cherry.py b/spyne/util/cherry.py
index f5b5cedc2..3fc222aed 100644
--- a/spyne/util/cherry.py
+++ b/spyne/util/cherry.py
@@ -2,14 +2,23 @@
# Source: https://www.digitalocean.com/community/tutorials/how-to-deploy-python-wsgi-applications-using-a-cherrypy-web-server-behind-nginx
import logging
+
import cherrypy
-def cherry_graft_and_start(wsgi_application, host="0.0.0.0", port=8080,
- num_threads=30, ssl_module=None, cert=None, key=None, cacert=None):
+def cherry_graft_and_start(
+ wsgi_application,
+ host="0.0.0.0",
+ port=8080,
+ num_threads=30,
+ ssl_module=None,
+ cert=None,
+ key=None,
+ cacert=None,
+):
logging.basicConfig(level=logging.DEBUG)
- logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
+ logging.getLogger("spyne.protocol.xml").setLevel(logging.DEBUG)
# Mount the application
cherrypy.tree.graft(wsgi_application, "/")
@@ -27,9 +36,9 @@ def cherry_graft_and_start(wsgi_application, host="0.0.0.0", port=8080,
# For SSL Support
if ssl_module is not None:
- server.ssl_module = ssl_module # eg. 'pyopenssl'
- server.ssl_certificate = cert # eg. 'ssl/certificate.crt'
- server.ssl_private_key = key # eg. 'ssl/private.key'
+ server.ssl_module = ssl_module # eg. 'pyopenssl'
+ server.ssl_certificate = cert # eg. 'ssl/certificate.crt'
+ server.ssl_private_key = key # eg. 'ssl/private.key'
server.ssl_certificate_chain = cacert # eg. 'ssl/bundle.crt'
# Subscribe this server
diff --git a/spyne/util/color.py b/spyne/util/color.py
index f12490a84..5655eb58a 100644
--- a/spyne/util/color.py
+++ b/spyne/util/color.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -19,33 +18,36 @@
from __future__ import absolute_import
-
try:
import colorama
- R = lambda s: ''.join((colorama.Fore.RED, colorama.Style.BRIGHT, s,
- colorama.Style.RESET_ALL))
- G = lambda s: ''.join((colorama.Fore.GREEN, colorama.Style.BRIGHT, s,
- colorama.Style.RESET_ALL))
- B = lambda s: ''.join((colorama.Fore.BLUE, colorama.Style.BRIGHT, s,
- colorama.Style.RESET_ALL))
- DARK_R = lambda s: ''.join((colorama.Fore.RED, s, colorama.Style.RESET_ALL))
- DARK_G = lambda s: ''.join((colorama.Fore.GREEN, s, colorama.Style.RESET_ALL))
- DARK_B = lambda s: ''.join((colorama.Fore.BLUE, s, colorama.Style.RESET_ALL))
+ R = lambda s: "".join(
+ (colorama.Fore.RED, colorama.Style.BRIGHT, s, colorama.Style.RESET_ALL)
+ )
+ G = lambda s: "".join(
+ (colorama.Fore.GREEN, colorama.Style.BRIGHT, s, colorama.Style.RESET_ALL)
+ )
+ B = lambda s: "".join(
+ (colorama.Fore.BLUE, colorama.Style.BRIGHT, s, colorama.Style.RESET_ALL)
+ )
+
+ DARK_R = lambda s: "".join((colorama.Fore.RED, s, colorama.Style.RESET_ALL))
+ DARK_G = lambda s: "".join((colorama.Fore.GREEN, s, colorama.Style.RESET_ALL))
+ DARK_B = lambda s: "".join((colorama.Fore.BLUE, s, colorama.Style.RESET_ALL))
- YEL = lambda s: ''.join((colorama.Fore.YELLOW, colorama.Style.BRIGHT, s,
- colorama.Style.RESET_ALL))
- MAG = lambda s: ''.join((colorama.Fore.MAGENTA, colorama.Style.BRIGHT, s,
- colorama.Style.RESET_ALL))
- CYA = lambda s: ''.join((colorama.Fore.CYAN, colorama.Style.BRIGHT, s,
- colorama.Style.RESET_ALL))
+ YEL = lambda s: "".join(
+ (colorama.Fore.YELLOW, colorama.Style.BRIGHT, s, colorama.Style.RESET_ALL)
+ )
+ MAG = lambda s: "".join(
+ (colorama.Fore.MAGENTA, colorama.Style.BRIGHT, s, colorama.Style.RESET_ALL)
+ )
+ CYA = lambda s: "".join(
+ (colorama.Fore.CYAN, colorama.Style.BRIGHT, s, colorama.Style.RESET_ALL)
+ )
- DARK_YEL = lambda s: ''.join((colorama.Fore.YELLOW, s,
- colorama.Style.RESET_ALL))
- DARK_MAG = lambda s: ''.join((colorama.Fore.MAGENTA, s,
- colorama.Style.RESET_ALL))
- DARK_CYA = lambda s: ''.join((colorama.Fore.CYAN, s,
- colorama.Style.RESET_ALL))
+ DARK_YEL = lambda s: "".join((colorama.Fore.YELLOW, s, colorama.Style.RESET_ALL))
+ DARK_MAG = lambda s: "".join((colorama.Fore.MAGENTA, s, colorama.Style.RESET_ALL))
+ DARK_CYA = lambda s: "".join((colorama.Fore.CYAN, s, colorama.Style.RESET_ALL))
except ImportError:
R = lambda s: s
@@ -62,7 +64,7 @@
DARK_CYA = lambda s: s
-if __name__ == '__main__':
+if __name__ == "__main__":
print(R("RED"))
print(G("GREEN"))
print(B("BLUE"))
diff --git a/spyne/util/coopmt.py b/spyne/util/coopmt.py
index 62fb14251..0bb473700 100644
--- a/spyne/util/coopmt.py
+++ b/spyne/util/coopmt.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -23,16 +22,17 @@
decorator.
"""
-
import logging
+
logger = logging.getLogger(__name__)
-from itertools import chain
from inspect import isgeneratorfunction
+from itertools import chain
class Break(Exception):
"""Raised for breaking out of infinite loops inside coroutines."""
+
pass
@@ -43,8 +43,13 @@ def start(*args, **kwargs):
try:
ret = func(*args, **kwargs)
except TypeError as e:
- logger.error("Function %r at %s:%d got error %r", func.func_name,
- func.__module__, func.__code__.co_firstlineno, e)
+ logger.error(
+ "Function %r at %s:%d got error %r",
+ func.func_name,
+ func.__module__,
+ func.__code__.co_firstlineno,
+ e,
+ )
raise
try:
@@ -54,7 +59,7 @@ def start(*args, **kwargs):
return None
except Exception as e:
- if not hasattr(e, 'logged'):
+ if not hasattr(e, "logged"):
logger.error("Exception in coroutine")
logger.exception(e)
try:
@@ -76,8 +81,13 @@ def start(*args, **kwargs):
try:
ret = func(*args, **kwargs)
except TypeError as e:
- logger.error("Function %r at %s:%d got error %r", func.func_name,
- func.__module__, func.__code__.co_firstlineno, e)
+ logger.error(
+ "Function %r at %s:%d got error %r",
+ func.func_name,
+ func.__module__,
+ func.__code__.co_firstlineno,
+ e,
+ )
raise
try:
@@ -87,7 +97,7 @@ def start(*args, **kwargs):
return None
except Exception as e:
- if not hasattr(e, 'logged'):
+ if not hasattr(e, "logged"):
logger.error("Exception in coroutine")
logger.exception(e)
try:
diff --git a/spyne/util/dictdoc.py b/spyne/util/dictdoc.py
index 77571cda2..5cf7b6de9 100644
--- a/spyne/util/dictdoc.py
+++ b/spyne/util/dictdoc.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -18,14 +17,13 @@
#
from spyne.context import FakeContext
-
-from spyne.protocol.dictdoc import HierDictDocument
-from spyne.protocol.dictdoc import SimpleDictDocument
+from spyne.protocol.dictdoc import HierDictDocument, SimpleDictDocument
try:
from spyne.protocol.json import JsonDocument
except ImportError as _import_error:
_local_import_error = _import_error
+
def JsonDocument(*args, **kwargs):
raise _local_import_error
@@ -34,6 +32,7 @@ def JsonDocument(*args, **kwargs):
from spyne.protocol.yaml import YamlDocument
except ImportError as _import_error:
_local_import_error = _import_error
+
def YamlDocument(*args, **kwargs):
raise _local_import_error
@@ -42,26 +41,36 @@ def YamlDocument(*args, **kwargs):
from spyne.protocol.msgpack import MessagePackDocument
except ImportError as _import_error:
_local_import_error = _import_error
+
def MessagePackDocument(*args, **kwargs):
raise _local_import_error
-from spyne.model.primitive import Double
-from spyne.model.primitive import Boolean
-from spyne.model.primitive import Decimal
-from spyne.model.primitive import Integer
+from spyne.model.primitive import Boolean, Decimal, Double, Integer
class _UtilProtocol(HierDictDocument):
- def __init__(self, app=None, validator=None, mime_type=None,
- ignore_uncap=False,
- # DictDocument specific
- ignore_wrappers=True,
- complex_as=dict,
- ordered=False):
-
- super(_UtilProtocol, self).__init__(app, validator, mime_type, ignore_uncap,
- ignore_wrappers, complex_as, ordered)
+ def __init__(
+ self,
+ app=None,
+ validator=None,
+ mime_type=None,
+ ignore_uncap=False,
+ # DictDocument specific
+ ignore_wrappers=True,
+ complex_as=dict,
+ ordered=False,
+ ):
+
+ super(_UtilProtocol, self).__init__(
+ app,
+ validator,
+ mime_type,
+ ignore_uncap,
+ ignore_wrappers,
+ complex_as,
+ ordered,
+ )
self._from_unicode_handlers[Double] = lambda cls, val: val
self._from_unicode_handlers[Boolean] = lambda cls, val: val
@@ -74,11 +83,16 @@ def __init__(self, app=None, validator=None, mime_type=None,
self._to_unicode_handlers[Integer] = lambda cls, val: val
-def get_doc_as_object(d, cls, ignore_wrappers=True, complex_as=list,
- protocol=_UtilProtocol, protocol_inst=None):
+def get_doc_as_object(
+ d,
+ cls,
+ ignore_wrappers=True,
+ complex_as=list,
+ protocol=_UtilProtocol,
+ protocol_inst=None,
+):
if protocol_inst is None:
- protocol_inst = protocol(ignore_wrappers=ignore_wrappers,
- complex_as=complex_as)
+ protocol_inst = protocol(ignore_wrappers=ignore_wrappers, complex_as=complex_as)
return protocol_inst._doc_to_object(None, cls, d)
@@ -87,14 +101,19 @@ def get_doc_as_object(d, cls, ignore_wrappers=True, complex_as=list,
"""DEPRECATED: Use ``get_doc_as_object`` instead"""
-def get_object_as_doc(o, cls=None, ignore_wrappers=True, complex_as=dict,
- protocol=_UtilProtocol, protocol_inst=None):
+def get_object_as_doc(
+ o,
+ cls=None,
+ ignore_wrappers=True,
+ complex_as=dict,
+ protocol=_UtilProtocol,
+ protocol_inst=None,
+):
if cls is None:
cls = o.__class__
if protocol_inst is None:
- protocol_inst = protocol(ignore_wrappers=ignore_wrappers,
- complex_as=complex_as)
+ protocol_inst = protocol(ignore_wrappers=ignore_wrappers, complex_as=complex_as)
retval = protocol_inst._object_to_doc(cls, o)
@@ -107,78 +126,118 @@ def get_object_as_doc(o, cls=None, ignore_wrappers=True, complex_as=dict,
get_object_as_dict = get_object_as_doc
"""DEPRECATED: Use ``get_object_as_doc`` instead."""
-def get_object_as_simple_dict(o, cls=None, hier_delim='.', prefix=None):
+
+def get_object_as_simple_dict(o, cls=None, hier_delim=".", prefix=None):
if cls is None:
cls = o.__class__
- return SimpleDictDocument(hier_delim=hier_delim) \
- .object_to_simple_dict(cls, o, prefix=prefix)
-
-
-def get_object_as_json(o, cls=None, ignore_wrappers=True, complex_as=list,
- encoding='utf8', polymorphic=False, indent=None, **kwargs):
+ return SimpleDictDocument(hier_delim=hier_delim).object_to_simple_dict(
+ cls, o, prefix=prefix
+ )
+
+
+def get_object_as_json(
+ o,
+ cls=None,
+ ignore_wrappers=True,
+ complex_as=list,
+ encoding="utf8",
+ polymorphic=False,
+ indent=None,
+ **kwargs,
+):
if cls is None:
cls = o.__class__
- prot = JsonDocument(ignore_wrappers=ignore_wrappers, complex_as=complex_as,
- polymorphic=polymorphic, indent=indent, **kwargs)
+ prot = JsonDocument(
+ ignore_wrappers=ignore_wrappers,
+ complex_as=complex_as,
+ polymorphic=polymorphic,
+ indent=indent,
+ **kwargs,
+ )
ctx = FakeContext(out_document=[prot._object_to_doc(cls, o)])
prot.create_out_string(ctx, encoding)
- return b''.join(ctx.out_string)
-
-
-def get_object_as_json_doc(o, cls=None, ignore_wrappers=True, complex_as=list,
- polymorphic=False, indent=None, **kwargs):
+ return b"".join(ctx.out_string)
+
+
+def get_object_as_json_doc(
+ o,
+ cls=None,
+ ignore_wrappers=True,
+ complex_as=list,
+ polymorphic=False,
+ indent=None,
+ **kwargs,
+):
if cls is None:
cls = o.__class__
- prot = JsonDocument(ignore_wrappers=ignore_wrappers, complex_as=complex_as,
- polymorphic=polymorphic, indent=indent, **kwargs)
+ prot = JsonDocument(
+ ignore_wrappers=ignore_wrappers,
+ complex_as=complex_as,
+ polymorphic=polymorphic,
+ indent=indent,
+ **kwargs,
+ )
return prot._object_to_doc(cls, o)
-def get_object_as_yaml(o, cls=None, ignore_wrappers=False, complex_as=dict,
- encoding='utf8', polymorphic=False):
+def get_object_as_yaml(
+ o,
+ cls=None,
+ ignore_wrappers=False,
+ complex_as=dict,
+ encoding="utf8",
+ polymorphic=False,
+):
if cls is None:
cls = o.__class__
- prot = YamlDocument(ignore_wrappers=ignore_wrappers, complex_as=complex_as,
- polymorphic=polymorphic)
- ctx = FakeContext(out_document=[prot._object_to_doc(cls,o)])
+ prot = YamlDocument(
+ ignore_wrappers=ignore_wrappers, complex_as=complex_as, polymorphic=polymorphic
+ )
+ ctx = FakeContext(out_document=[prot._object_to_doc(cls, o)])
prot.create_out_string(ctx, encoding)
- return b''.join(ctx.out_string)
+ return b"".join(ctx.out_string)
-def get_object_as_yaml_doc(o, cls=None, ignore_wrappers=False, complex_as=dict,
- polymorphic=False):
+def get_object_as_yaml_doc(
+ o, cls=None, ignore_wrappers=False, complex_as=dict, polymorphic=False
+):
if cls is None:
cls = o.__class__
- prot = YamlDocument(ignore_wrappers=ignore_wrappers, complex_as=complex_as,
- polymorphic=polymorphic)
+ prot = YamlDocument(
+ ignore_wrappers=ignore_wrappers, complex_as=complex_as, polymorphic=polymorphic
+ )
return prot._object_to_doc(cls, o)
-def get_object_as_msgpack(o, cls=None, ignore_wrappers=False, complex_as=dict,
- polymorphic=False):
+def get_object_as_msgpack(
+ o, cls=None, ignore_wrappers=False, complex_as=dict, polymorphic=False
+):
if cls is None:
cls = o.__class__
- prot = MessagePackDocument(ignore_wrappers=ignore_wrappers,
- complex_as=complex_as, polymorphic=polymorphic)
- ctx = FakeContext(out_document=[prot._object_to_doc(cls,o)])
+ prot = MessagePackDocument(
+ ignore_wrappers=ignore_wrappers, complex_as=complex_as, polymorphic=polymorphic
+ )
+ ctx = FakeContext(out_document=[prot._object_to_doc(cls, o)])
prot.create_out_string(ctx)
- return b''.join(ctx.out_string)
+ return b"".join(ctx.out_string)
-def get_object_as_msgpack_doc(o, cls=None, ignore_wrappers=False,
- complex_as=dict, polymorphic=False):
+def get_object_as_msgpack_doc(
+ o, cls=None, ignore_wrappers=False, complex_as=dict, polymorphic=False
+):
if cls is None:
cls = o.__class__
- prot = MessagePackDocument(ignore_wrappers=ignore_wrappers,
- complex_as=complex_as, polymorphic=polymorphic)
+ prot = MessagePackDocument(
+ ignore_wrappers=ignore_wrappers, complex_as=complex_as, polymorphic=polymorphic
+ )
return prot._object_to_doc(cls, o)
@@ -186,13 +245,12 @@ def get_object_as_msgpack_doc(o, cls=None, ignore_wrappers=False,
def json_loads(s, cls, protocol=JsonDocument, **kwargs):
if s is None:
return None
- if s == '':
+ if s == "":
return None
prot = protocol(**kwargs)
ctx = FakeContext(in_string=[s])
prot.create_in_document(ctx)
- return prot._doc_to_object(None, cls, ctx.in_document,
- validator=prot.validator)
+ return prot._doc_to_object(None, cls, ctx.in_document, validator=prot.validator)
get_json_as_object = json_loads
@@ -201,13 +259,12 @@ def json_loads(s, cls, protocol=JsonDocument, **kwargs):
def yaml_loads(s, cls, protocol=YamlDocument, ignore_wrappers=False, **kwargs):
if s is None:
return None
- if s == '' or s == b'':
+ if s == "" or s == b"":
return None
prot = protocol(ignore_wrappers=ignore_wrappers, **kwargs)
ctx = FakeContext(in_string=[s])
prot.create_in_document(ctx)
- retval = prot._doc_to_object(None, cls, ctx.in_document,
- validator=prot.validator)
+ retval = prot._doc_to_object(None, cls, ctx.in_document, validator=prot.validator)
return retval
diff --git a/spyne/util/django.py b/spyne/util/django.py
index 688c69efd..b45a43cd8 100644
--- a/spyne/util/django.py
+++ b/spyne/util/django.py
@@ -27,35 +27,32 @@
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
import re
-
from itertools import chain
-from django.core.exceptions import (ImproperlyConfigured, ObjectDoesNotExist,
- ValidationError as DjValidationError)
-from django.core.validators import (slug_re,
- MinLengthValidator, MaxLengthValidator)
+from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
+from django.core.exceptions import ValidationError as DjValidationError
+from django.core.validators import MaxLengthValidator, MinLengthValidator, slug_re
+
try:
from django.core.validators import comma_separated_int_list_re
except ImportError:
- comma_separated_int_list_re = re.compile(r'^[\d,]+$')
+ comma_separated_int_list_re = re.compile(r"^[\d,]+$")
-from spyne.error import (ResourceNotFoundError, ValidationError as
- BaseValidationError, Fault)
+from spyne.error import Fault, ResourceNotFoundError
+from spyne.error import ValidationError as BaseValidationError
from spyne.model import primitive
-from spyne.model.complex import ComplexModelMeta, ComplexModelBase
+from spyne.model.complex import ComplexModelBase, ComplexModelMeta
from spyne.service import Service
from spyne.util.cdict import cdict
from spyne.util.odict import odict
-from spyne.util.six import add_metaclass
-
# regex is based on http://www.w3.org/TR/xforms20/#xforms:email
email_re = re.compile(
- r"[A-Za-z0-9!#-'\*\+\-/=\?\^_`\{-~]+"
- r"(\.[A-Za-z0-9!#-'\*\+\-/=\?\^_`\{-~]+)*@"
+ r"[A-Za-z0-9!#-'\*\+\-/=\?\^_`\{-~]+" r"(\.[A-Za-z0-9!#-'\*\+\-/=\?\^_`\{-~]+)*@"
# domain part is either a single symbol
r"("
# or have at least two symbols
@@ -63,29 +60,32 @@
# domain should contain at least 2 parts, the last one is TLD
r"[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?\.)+"
# TLD should contain only letters, at least 2
- r"[A-Za-z]{2,}", re.IGNORECASE)
+ r"[A-Za-z]{2,}",
+ re.IGNORECASE,
+)
def _handle_minlength(validator, params):
new_min = validator.limit_value
- old_min = params.setdefault('min_len', new_min)
- params['min_len'] = max(old_min, new_min)
+ old_min = params.setdefault("min_len", new_min)
+ params["min_len"] = max(old_min, new_min)
def _handle_maxlength(validator, params):
new_max = validator.limit_value
- old_max = params.setdefault('max_len', new_max)
- params['max_len'] = min(old_max, new_max)
+ old_max = params.setdefault("max_len", new_max)
+ params["max_len"] = min(old_max, new_max)
class BaseDjangoFieldMapper(object):
-
"""Abstrace base class for field mappers."""
- _VALIDATOR_HANDLERS = cdict({
- MinLengthValidator: _handle_minlength,
- MaxLengthValidator: _handle_maxlength,
- })
+ _VALIDATOR_HANDLERS = cdict(
+ {
+ MinLengthValidator: _handle_minlength,
+ MaxLengthValidator: _handle_maxlength,
+ }
+ )
@staticmethod
def is_field_nullable(field, **kwargs):
@@ -114,11 +114,12 @@ def map(self, field, **kwargs):
required = not (field.has_default() or blank or field.primary_key)
if field.has_default():
- params['default'] = field.get_default()
+ params["default"] = field.get_default()
spyne_model = self.get_spyne_model(field, **kwargs)
- customized_model = spyne_model(nullable=nullable,
- min_occurs=int(required), **params)
+ customized_model = spyne_model(
+ nullable=nullable, min_occurs=int(required), **params
+ )
return (field.attname, customized_model)
@@ -134,7 +135,6 @@ def _process_validators(self, validators, params):
class DjangoFieldMapper(BaseDjangoFieldMapper):
-
"""Basic mapper for django fields."""
def __init__(self, spyne_model):
@@ -147,7 +147,6 @@ def get_spyne_model(self, field, **kwargs):
class DecimalMapper(DjangoFieldMapper):
-
"""Mapper for DecimalField."""
def map(self, field, **kwargs):
@@ -157,15 +156,16 @@ def map(self, field, **kwargs):
"""
params = kwargs.copy()
- params.update({
- 'total_digits': field.max_digits,
- 'fraction_digits': field.decimal_places,
- })
+ params.update(
+ {
+ "total_digits": field.max_digits,
+ "fraction_digits": field.decimal_places,
+ }
+ )
return super(DecimalMapper, self).map(field, **params)
class RelationMapper(BaseDjangoFieldMapper):
-
"""Mapper for relation fields (ForeignKey, OneToOneField)."""
def __init__(self, django_model_mapper):
@@ -179,13 +179,18 @@ def is_field_blank(field, **kwargs):
Otherwise use basic behaviour.
"""
- optional_relations = kwargs.get('optional_relations', False)
- return (optional_relations or
- BaseDjangoFieldMapper.is_field_blank(field, **kwargs))
+ optional_relations = kwargs.get("optional_relations", False)
+ return optional_relations or BaseDjangoFieldMapper.is_field_blank(
+ field, **kwargs
+ )
def get_spyne_model(self, field, **kwargs):
"""Return spyne model configured by related field."""
- related_field = field.rel.get_related_field() if hasattr(field, 'rel') else field.remote_field.get_related_field()
+ related_field = (
+ field.rel.get_related_field()
+ if hasattr(field, "rel")
+ else field.remote_field.get_related_field()
+ )
field_type = related_field.__class__.__name__
field_mapper = self.django_model_mapper.get_field_mapper(field_type)
@@ -194,7 +199,6 @@ def get_spyne_model(self, field, **kwargs):
class DjangoModelMapper(object):
-
r"""Mapper from django models to spyne complex models.
You can extend it registering new field types: ::
@@ -218,7 +222,6 @@ def map(self, field, **kwargs):
field_mapper_class = DjangoFieldMapper
class UnknownFieldMapperException(Exception):
-
"""Raises when there is no field mapper for given django_type."""
def __init__(self, django_spyne_models=()):
@@ -240,7 +243,8 @@ def get_field_mapper(self, django_type):
return self._registry[django_type]
except KeyError:
raise self.UnknownFieldMapperException(
- 'No mapper for field type {0}'.format(django_type))
+ "No mapper for field type {0}".format(django_type)
+ )
def register(self, django_type, spyne_model):
"""Register default field mapper for django_type and spyne_model.
@@ -263,32 +267,39 @@ def register_field_mapper(self, django_type, field_mapper):
@staticmethod
def get_all_field_names(meta):
- if hasattr(meta, 'get_all_field_names'):
+ if hasattr(meta, "get_all_field_names"):
return meta.get_all_field_names()
- return list(set(chain.from_iterable(
- (field.name, field.attname) if hasattr(field, 'attname') else (
- field.name,)
- for field in meta.get_fields()
- # For complete backwards compatibility, you may want to exclude
- # GenericForeignKey from the results.
- if not (field.many_to_one and field.related_model is None)
- )))
+ return list(
+ set(
+ chain.from_iterable(
+ (
+ (field.name, field.attname)
+ if hasattr(field, "attname")
+ else (field.name,)
+ )
+ for field in meta.get_fields()
+ # For complete backwards compatibility, you may want to exclude
+ # GenericForeignKey from the results.
+ if not (field.many_to_one and field.related_model is None)
+ )
+ )
+ )
@staticmethod
def _get_fields(django_model, exclude=None):
field_names = set(exclude) if exclude is not None else set()
meta = django_model._meta # pylint: disable=W0212
- unknown_fields_names = \
- field_names.difference(DjangoModelMapper.get_all_field_names(meta))
+ unknown_fields_names = field_names.difference(
+ DjangoModelMapper.get_all_field_names(meta)
+ )
if unknown_fields_names:
raise ImproperlyConfigured(
- 'Unknown field names: {0}'
- .format(', '.join(unknown_fields_names)))
+ "Unknown field names: {0}".format(", ".join(unknown_fields_names))
+ )
- return [field for field in meta.fields if field.name not in
- field_names]
+ return [field for field in meta.fields if field.name not in field_names]
def map(self, django_model, exclude=None, **kwargs):
"""Prepare dict of model fields mapped to spyne models.
@@ -313,10 +324,11 @@ def map(self, django_model, exclude=None, **kwargs):
if not (field.has_default() or field.null):
# field is required
raise self.UnknownFieldMapperException(
- 'No mapper for field type {0}'.format(field_type))
+ "No mapper for field type {0}".format(field_type)
+ )
else:
# skip this field
- logger.info('Field {0} is skipped from mapping.')
+ logger.info("Field {0} is skipped from mapping.")
continue
attr_name, spyne_model = field_mapper.map(field, **kwargs)
@@ -337,10 +349,10 @@ def strip_regex_metachars(pattern):
start = 0
till = len(pattern)
- if pattern.startswith('^'):
+ if pattern.startswith("^"):
start = 1
- if pattern.endswith('$'):
+ if pattern.endswith("$"):
till -= 1
return pattern[start:till]
@@ -349,39 +361,48 @@ def strip_regex_metachars(pattern):
# django's own slug_re.pattern is invalid according to xml schema -- it doesn't
# like the location of the dash character. using the equivalent pattern accepted
# by xml schema here.
-SLUG_RE_PATTERN = '[a-zA-Z0-9_-]+'
+SLUG_RE_PATTERN = "[a-zA-Z0-9_-]+"
DEFAULT_FIELD_MAP = (
- ('AutoField', primitive.Integer32),
- ('CharField', primitive.NormalizedString),
- ('SlugField', primitive.Unicode(
- type_name='Slug', pattern=strip_regex_metachars(SLUG_RE_PATTERN))),
- ('TextField', primitive.Unicode),
- ('EmailField', primitive.Unicode(
- type_name='Email', pattern=strip_regex_metachars(email_re.pattern))),
- ('CommaSeparatedIntegerField', primitive.Unicode(
- type_name='CommaSeparatedField',
- pattern=strip_regex_metachars(comma_separated_int_list_re.pattern))),
- ('URLField', primitive.AnyUri),
- ('FilePathField', primitive.Unicode),
-
- ('BooleanField', primitive.Boolean),
- ('NullBooleanField', primitive.Boolean),
- ('IntegerField', primitive.Integer),
- ('BigIntegerField', primitive.Integer64),
- ('PositiveIntegerField', primitive.UnsignedInteger32),
- ('SmallIntegerField', primitive.Integer16),
- ('PositiveSmallIntegerField', primitive.UnsignedInteger16),
- ('FloatField', primitive.Double),
-
- ('TimeField', primitive.Time),
- ('DateField', primitive.Date),
- ('DateTimeField', primitive.DateTime),
-
+ ("AutoField", primitive.Integer32),
+ ("CharField", primitive.NormalizedString),
+ (
+ "SlugField",
+ primitive.Unicode(
+ type_name="Slug", pattern=strip_regex_metachars(SLUG_RE_PATTERN)
+ ),
+ ),
+ ("TextField", primitive.Unicode),
+ (
+ "EmailField",
+ primitive.Unicode(
+ type_name="Email", pattern=strip_regex_metachars(email_re.pattern)
+ ),
+ ),
+ (
+ "CommaSeparatedIntegerField",
+ primitive.Unicode(
+ type_name="CommaSeparatedField",
+ pattern=strip_regex_metachars(comma_separated_int_list_re.pattern),
+ ),
+ ),
+ ("URLField", primitive.AnyUri),
+ ("FilePathField", primitive.Unicode),
+ ("BooleanField", primitive.Boolean),
+ ("NullBooleanField", primitive.Boolean),
+ ("IntegerField", primitive.Integer),
+ ("BigIntegerField", primitive.Integer64),
+ ("PositiveIntegerField", primitive.UnsignedInteger32),
+ ("SmallIntegerField", primitive.Integer16),
+ ("PositiveSmallIntegerField", primitive.UnsignedInteger16),
+ ("FloatField", primitive.Double),
+ ("TimeField", primitive.Time),
+ ("DateField", primitive.Date),
+ ("DateTimeField", primitive.DateTime),
# simple fixed defaults for relation fields
- ('ForeignKey', primitive.Integer32),
- ('OneToOneField', primitive.Integer32),
+ ("ForeignKey", primitive.Integer32),
+ ("OneToOneField", primitive.Integer32),
)
@@ -394,59 +415,56 @@ def model_mapper_factory(mapper_class, field_map):
model_mapper = mapper_class(field_map)
# register relation field mappers that are aware of related field type
- model_mapper.register_field_mapper(
- 'ForeignKey', RelationMapper(model_mapper))
+ model_mapper.register_field_mapper("ForeignKey", RelationMapper(model_mapper))
- model_mapper.register_field_mapper(
- 'OneToOneField', RelationMapper(model_mapper))
+ model_mapper.register_field_mapper("OneToOneField", RelationMapper(model_mapper))
- model_mapper.register_field_mapper('DecimalField',
- DecimalMapper(primitive.Decimal))
+ model_mapper.register_field_mapper("DecimalField", DecimalMapper(primitive.Decimal))
return model_mapper
-default_model_mapper = model_mapper_factory(DjangoModelMapper,
- DEFAULT_FIELD_MAP)
+default_model_mapper = model_mapper_factory(DjangoModelMapper, DEFAULT_FIELD_MAP)
class DjangoComplexModelMeta(ComplexModelMeta):
-
"""Meta class for complex spyne models representing Django models."""
def __new__(mcs, name, bases, attrs): # pylint: disable=C0202
"""Populate new complex type from configured Django model."""
super_new = super(DjangoComplexModelMeta, mcs).__new__
- abstract = bool(attrs.get('__abstract__', False))
+ abstract = bool(attrs.get("__abstract__", False))
if abstract:
# skip processing of abstract models
return super_new(mcs, name, bases, attrs)
- attributes = attrs.get('Attributes')
+ attributes = attrs.get("Attributes")
if attributes is None:
- raise ImproperlyConfigured('You have to define Attributes and '
- 'specify Attributes.django_model')
+ raise ImproperlyConfigured(
+ "You have to define Attributes and " "specify Attributes.django_model"
+ )
- if getattr(attributes, 'django_model', None) is None:
- raise ImproperlyConfigured('You have to define django_model '
- 'attribute in Attributes')
+ if getattr(attributes, "django_model", None) is None:
+ raise ImproperlyConfigured(
+ "You have to define django_model " "attribute in Attributes"
+ )
- mapper = getattr(attributes, 'django_mapper', default_model_mapper)
+ mapper = getattr(attributes, "django_mapper", default_model_mapper)
attributes.django_mapper = mapper
- exclude = getattr(attributes, 'django_exclude', None)
- optional_relations = getattr(attributes, 'django_optional_relations',
- False)
- spyne_attrs = mapper.map(attributes.django_model, exclude=exclude,
- optional_relations=optional_relations)
+ exclude = getattr(attributes, "django_exclude", None)
+ optional_relations = getattr(attributes, "django_optional_relations", False)
+ spyne_attrs = mapper.map(
+ attributes.django_model,
+ exclude=exclude,
+ optional_relations=optional_relations,
+ )
spyne_attrs.update(attrs)
return super_new(mcs, name, bases, spyne_attrs)
-@add_metaclass(DjangoComplexModelMeta)
-class DjangoComplexModel(ComplexModelBase):
-
+class DjangoComplexModel(ComplexModelBase, metaclass=DjangoComplexModelMeta):
"""Base class with Django model mapping support.
Sample usage: ::
@@ -492,7 +510,6 @@ class Attributes(DjangoComplexModel.Attributes):
class ObjectNotFoundError(ResourceNotFoundError):
-
"""Fault constructed from `model.DoesNotExist` exception."""
def __init__(self, does_not_exist_exc):
@@ -501,12 +518,13 @@ def __init__(self, does_not_exist_exc):
object_name = message.split()[0]
# we do not want to reuse initialization of ResourceNotFoundError
Fault.__init__(
- self, faultcode='Client.{0}NotFound'.format(object_name),
- faultstring=message)
+ self,
+ faultcode="Client.{0}NotFound".format(object_name),
+ faultstring=message,
+ )
class ValidationError(BaseValidationError):
-
"""Fault constructed from `ValidationError` exception."""
def __init__(self, validation_error_exc):
@@ -514,12 +532,13 @@ def __init__(self, validation_error_exc):
message = str(validation_error_exc)
# we do not want to reuse initialization of BaseValidationError
Fault.__init__(
- self, faultcode='Client.{0}'.format(
- type(validation_error_exc).__name__), faultstring=message)
+ self,
+ faultcode="Client.{0}".format(type(validation_error_exc).__name__),
+ faultstring=message,
+ )
class DjangoService(Service):
-
"""Service with common Django exception handling."""
@classmethod
diff --git a/spyne/util/dyninit.py b/spyne/util/dyninit.py
index 21eb775bc..6412c0acb 100644
--- a/spyne/util/dyninit.py
+++ b/spyne/util/dyninit.py
@@ -19,30 +19,25 @@
from datetime import date, datetime
-from spyne import D, Integer, ModelBase, Date, DateTime, IpAddress, Decimal, \
- Boolean
+from spyne import Boolean, D, Date, DateTime, Decimal, Integer, IpAddress, ModelBase
from spyne.protocol import ProtocolBase
-from spyne.util import six
from spyne.util.cdict import cdict
+BOOL_VALUES_BYTES_TRUE = (b"t", b"1", b"on", b"yes", b"true")
+BOOL_VALUES_STR_TRUE = ("t", "1", "on", "yes", "true")
-BOOL_VALUES_BYTES_TRUE = (b't', b'1', b'on', b'yes', b'true')
-BOOL_VALUES_STR_TRUE = (u't', u'1', u'on', u'yes', u'true')
+BOOL_VALUES_BYTES_FALSE = (b"f", b"0", b"off", b"no", b"false")
+BOOL_VALUES_STR_FALSE = ("f", "0", "off", "no", "false")
-BOOL_VALUES_BYTES_FALSE = (b'f', b'0', b'off', b'no', b'false')
-BOOL_VALUES_STR_FALSE = (u'f', u'0', u'off', u'no', u'false')
+BOOL_VALUES_NONE = (None, "")
-BOOL_VALUES_NONE = (None, '')
-
-if six.PY2:
- bytes = str
-else:
- unicode = str
+unicode = str
_prot = ProtocolBase()
+
def _bool_from_int(i):
if i in (0, 1):
return i == 1
@@ -78,60 +73,82 @@ def _bool_from_str(s):
raise ValueError(s)
-MAP = cdict({
- ModelBase: cdict({
- object: lambda _: _,
- bytes: lambda _: _.strip(),
- unicode: lambda _: _.strip(),
- }),
-
- Decimal: cdict({
- D: lambda d: d,
- int: lambda i: D(i),
- bytes: lambda s: None if s.strip() == '' else D(s.strip()),
- unicode: lambda s: None if s.strip() == u'' else D(s.strip()),
- }),
-
- Boolean: cdict({
- D: lambda d: _bool_from_int(int(d)),
- int: _bool_from_int,
- bytes: _bool_from_bytes,
- unicode: _bool_from_str,
- }),
-
- Integer: cdict({
- D: lambda _: _,
- int: lambda _: _,
- bytes: lambda s: None if s.strip() == '' else int(s.strip()),
- unicode: lambda s: None if s.strip() == u'' else int(s.strip()),
- }),
-
- Date: cdict({
- date: lambda _: _,
- datetime: lambda _: _.date(),
- object: lambda _:_,
- bytes: lambda s: None if s.strip() in ('', '0000-00-00')
- else _prot.date_from_unicode(Date, s.strip()),
- unicode: lambda s: None if s.strip() in (u'', u'0000-00-00')
- else _prot.date_from_unicode(Date, s.strip()),
- }),
-
- DateTime: cdict({
- date: lambda _: datetime(date.year, date.month, date.day),
- datetime: lambda _: _,
- object: lambda _:_,
- bytes: lambda s: None if s.strip() in ('', '0000-00-00 00:00:00')
- else _prot.datetime_from_unicode(DateTime, s.strip()),
- unicode: lambda s: None if s.strip() in (u'', u'0000-00-00 00:00:00')
- else _prot.datetime_from_unicode(DateTime, s.strip()),
- }),
-
- IpAddress: cdict({
- object: lambda _: _,
- bytes: lambda s: None if s.strip() == '' else s.strip(),
- unicode: lambda s: None if s.strip() == u'' else s.strip(),
- })
-})
+MAP = cdict(
+ {
+ ModelBase: cdict(
+ {
+ object: lambda _: _,
+ bytes: lambda _: _.strip(),
+ unicode: lambda _: _.strip(),
+ }
+ ),
+ Decimal: cdict(
+ {
+ D: lambda d: d,
+ int: lambda i: D(i),
+ bytes: lambda s: None if s.strip() == "" else D(s.strip()),
+ unicode: lambda s: None if s.strip() == "" else D(s.strip()),
+ }
+ ),
+ Boolean: cdict(
+ {
+ D: lambda d: _bool_from_int(int(d)),
+ int: _bool_from_int,
+ bytes: _bool_from_bytes,
+ unicode: _bool_from_str,
+ }
+ ),
+ Integer: cdict(
+ {
+ D: lambda _: _,
+ int: lambda _: _,
+ bytes: lambda s: None if s.strip() == "" else int(s.strip()),
+ unicode: lambda s: None if s.strip() == "" else int(s.strip()),
+ }
+ ),
+ Date: cdict(
+ {
+ date: lambda _: _,
+ datetime: lambda _: _.date(),
+ object: lambda _: _,
+ bytes: lambda s: (
+ None
+ if s.strip() in ("", "0000-00-00")
+ else _prot.date_from_unicode(Date, s.strip())
+ ),
+ unicode: lambda s: (
+ None
+ if s.strip() in ("", "0000-00-00")
+ else _prot.date_from_unicode(Date, s.strip())
+ ),
+ }
+ ),
+ DateTime: cdict(
+ {
+ date: lambda _: datetime(date.year, date.month, date.day),
+ datetime: lambda _: _,
+ object: lambda _: _,
+ bytes: lambda s: (
+ None
+ if s.strip() in ("", "0000-00-00 00:00:00")
+ else _prot.datetime_from_unicode(DateTime, s.strip())
+ ),
+ unicode: lambda s: (
+ None
+ if s.strip() in ("", "0000-00-00 00:00:00")
+ else _prot.datetime_from_unicode(DateTime, s.strip())
+ ),
+ }
+ ),
+ IpAddress: cdict(
+ {
+ object: lambda _: _,
+ bytes: lambda s: None if s.strip() == "" else s.strip(),
+ unicode: lambda s: None if s.strip() == "" else s.strip(),
+ }
+ ),
+ }
+)
def dynamic_init(cls, **kwargs):
diff --git a/spyne/util/email.py b/spyne/util/email.py
index 0da579ceb..224ea8ba7 100644
--- a/spyne/util/email.py
+++ b/spyne/util/email.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -20,28 +19,25 @@
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
import getpass
import inspect
-import traceback
-import smtplib
import mimetypes
-
-from socket import gethostname
-from subprocess import Popen, PIPE
-
-from email.utils import COMMASPACE, formatdate
+import smtplib
+import traceback
from email import message_from_string
-from email.mime.text import MIMEText
+from email.encoders import encode_base64
+from email.mime.application import MIMEApplication
from email.mime.image import MIMEImage
from email.mime.message import MIMEMessage
from email.mime.multipart import MIMEMultipart
-from email.mime.application import MIMEApplication
from email.mime.nonmultipart import MIMENonMultipart
-from email.encoders import encode_base64
-
-from spyne.util import six
+from email.mime.text import MIMEText
+from email.utils import COMMASPACE, formatdate
+from socket import gethostname
+from subprocess import PIPE, Popen
def email_exception(exception_address, message="", bcc=None):
@@ -50,20 +46,20 @@ def email_exception(exception_address, message="", bcc=None):
mod = inspect.getmodule(frm[0])
module_name = mod.__name__ if mod else frm[1]
- sender = 'robot@spyne.io'
+ sender = "robot@spyne.io"
recipients = [exception_address]
if bcc is not None:
recipients.extend(bcc)
- error_str = ("%s\n\n%s" % (message, traceback.format_exc()))
- msg = MIMEText(error_str.encode('utf8'), 'plain', 'utf8')
- msg['To'] = exception_address
- msg['From'] = 'Spyne '
- msg['Date'] = formatdate()
- msg['Subject'] = "(%s@%s) %s" % (getpass.getuser(), gethostname(), module_name)
+ error_str = "%s\n\n%s" % (message, traceback.format_exc())
+ msg = MIMEText(error_str.encode("utf8"), "plain", "utf8")
+ msg["To"] = exception_address
+ msg["From"] = "Spyne "
+ msg["Date"] = formatdate()
+ msg["Subject"] = "(%s@%s) %s" % (getpass.getuser(), gethostname(), module_name)
try:
- smtp_object = smtplib.SMTP('localhost')
+ smtp_object = smtplib.SMTP("localhost")
smtp_object.sendmail(sender, recipients, msg.as_string())
logger.error("Error email sent")
@@ -72,40 +68,37 @@ def email_exception(exception_address, message="", bcc=None):
logger.exception(e)
-def email_text_smtp(addresses, sender=None, subject='', message="",
- host='localhost', port=25):
+def email_text_smtp(
+ addresses, sender=None, subject="", message="", host="localhost", port=25
+):
if sender is None:
- sender = 'Spyne '
+ sender = "Spyne "
exc = traceback.format_exc()
if exc is not None:
- message = (u"%s\n\n%s" % (message, exc))
- msg = MIMEText(message.encode('utf8'), 'plain', 'utf8')
- msg['To'] = COMMASPACE.join(addresses)
- msg['From'] = sender
- msg['Date'] = formatdate()
- msg['Subject'] = subject
+ message = "%s\n\n%s" % (message, exc)
+ msg = MIMEText(message.encode("utf8"), "plain", "utf8")
+ msg["To"] = COMMASPACE.join(addresses)
+ msg["From"] = sender
+ msg["Date"] = formatdate()
+ msg["Subject"] = subject
smtp_object = smtplib.SMTP(host, port)
- if six.PY2:
- smtp_object.sendmail(sender, addresses, msg.as_string())
- else:
- smtp_object.sendmail(sender, addresses, msg.as_bytes())
+ smtp_object.sendmail(sender, addresses, msg.as_bytes())
logger.info("Text email sent to: %r.", addresses)
-def email_text(addresses, sender=None, subject="", message="", bcc=None,
- att=None):
+def email_text(addresses, sender=None, subject="", message="", bcc=None, att=None):
if att is None:
att = {}
if sender is None:
- sender = 'Spyne '
+ sender = "Spyne "
exc = traceback.format_exc()
- if exc is not None and exc != 'None\n' and exc != 'NoneType: None\n':
- message = (u"%s\n\n%s" % (message, exc))
- msg = MIMEText(message.encode('utf8'), 'plain', 'utf8')
+ if exc is not None and exc != "None\n" and exc != "NoneType: None\n":
+ message = "%s\n\n%s" % (message, exc)
+ msg = MIMEText(message.encode("utf8"), "plain", "utf8")
if len(att) > 0:
newmsg = MIMEMultipart()
newmsg.attach(msg)
@@ -114,9 +107,9 @@ def email_text(addresses, sender=None, subject="", message="", bcc=None,
if mime_type == "message/rfc822":
part = MIMEMessage(message_from_string(v))
elif mime_type.startswith("image/"):
- part = MIMEImage(v, mime_type.rsplit('/', 1)[-1])
+ part = MIMEImage(v, mime_type.rsplit("/", 1)[-1])
elif mime_type is not None:
- mime_type_main, mime_type_sub = mime_type.split('/', 1)
+ mime_type_main, mime_type_sub = mime_type.split("/", 1)
part = MIMENonMultipart(mime_type_main, mime_type_sub)
part.set_payload(v)
encode_base64(part)
@@ -124,24 +117,21 @@ def email_text(addresses, sender=None, subject="", message="", bcc=None,
part = MIMEApplication(v)
newmsg.attach(part)
- part.add_header('Content-Disposition', 'attachment', filename=k)
+ part.add_header("Content-Disposition", "attachment", filename=k)
msg = newmsg
- msg['To'] = COMMASPACE.join(addresses)
- msg['From'] = sender
- msg['Date'] = formatdate()
- msg['Subject'] = subject
+ msg["To"] = COMMASPACE.join(addresses)
+ msg["From"] = sender
+ msg["Date"] = formatdate()
+ msg["Subject"] = subject
- cmd = ["/usr/sbin/sendmail", "-oi", '--']
+ cmd = ["/usr/sbin/sendmail", "-oi", "--"]
cmd.extend(addresses)
if bcc is not None:
cmd.extend(bcc)
p = Popen(cmd, stdin=PIPE)
- if six.PY2:
- p.communicate(msg.as_string())
- else:
- p.communicate(msg.as_bytes())
+ p.communicate(msg.as_bytes())
logger.info("Text email sent to: %r.", addresses)
diff --git a/spyne/util/etreeconv.py b/spyne/util/etreeconv.py
index ea5a0067e..842818348 100644
--- a/spyne/util/etreeconv.py
+++ b/spyne/util/etreeconv.py
@@ -27,7 +27,6 @@
from lxml import etree
-from spyne.util import six
from spyne.util.odict import odict
@@ -39,7 +38,7 @@ def root_dict_to_etree(d):
assert len(d) == 1, "Incoming dict len must be exactly 1. Data: %r" % d
- key, = d.keys()
+ (key,) = d.keys()
retval = etree.Element(key)
for val in d.values():
break
@@ -49,7 +48,7 @@ def root_dict_to_etree(d):
if isinstance(val, dict) or isinstance(val, odict):
dict_to_etree(val, retval)
- elif not isinstance(val, Sized) or isinstance(val, six.string_types):
+ elif not isinstance(val, Sized) or isinstance(val, str):
retval.text = str(val)
else:
for a in val:
@@ -68,7 +67,7 @@ def dict_to_etree(d, parent):
if v is None:
etree.SubElement(parent, k)
- elif isinstance(v, six.string_types):
+ elif isinstance(v, str):
etree.SubElement(parent, k).text = v
elif isinstance(v, dict) or isinstance(v, odict):
@@ -121,10 +120,10 @@ def etree_to_dict(element, iterable=(list, list.append)):
def etree_strip_namespaces(element):
"""Removes any namespace information form the given element recursively."""
- retval = etree.Element(element.tag.rpartition('}')[-1])
+ retval = etree.Element(element.tag.rpartition("}")[-1])
retval.text = element.text
for a in element.attrib:
- retval.attrib[a.rpartition('}')[-1]] = element.attrib[a]
+ retval.attrib[a.rpartition("}")[-1]] = element.attrib[a]
for e in element:
retval.append(etree_strip_namespaces(e))
diff --git a/spyne/util/fileproxy.py b/spyne/util/fileproxy.py
index 878c3a2aa..3fb4360b0 100644
--- a/spyne/util/fileproxy.py
+++ b/spyne/util/fileproxy.py
@@ -1,4 +1,3 @@
-
#
# Copyright (C) 2013-2014 by Hong Minhee
#
@@ -22,10 +21,9 @@
#
import os
+from collections.abc import Iterator
-from spyne.util.six.moves.collections_abc import Iterator
-
-__all__ = 'FileProxy', 'ReusableFileProxy', 'SeekableFileProxy'
+__all__ = "FileProxy", "ReusableFileProxy", "SeekableFileProxy"
class FileProxy(Iterator):
@@ -41,7 +39,7 @@ def __init__(self, wrapped):
def __iter__(self):
f = self.wrapped
- it = getattr(f, '__iter__', None)
+ it = getattr(f, "__iter__", None)
if callable(it):
return it()
return self
@@ -50,7 +48,7 @@ def __next__(self):
"""Implementation of :class:`collections.Iterator` protocol."""
line = self.readline()
if not line:
- raise StopIteration('hit eof')
+ raise StopIteration("hit eof")
return line
next = __next__
diff --git a/spyne/util/gencpp.py b/spyne/util/gencpp.py
index 01ad20658..2a68cfdb8 100644
--- a/spyne/util/gencpp.py
+++ b/spyne/util/gencpp.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -22,7 +21,8 @@
import sys
-INDENT = ' '
+INDENT = " "
+
class Object(object):
def __init__(self):
@@ -39,10 +39,10 @@ def _comment_before_to_stream(self, ostr, indent):
ostr.write("/**\n")
ostr.write(INDENT * indent)
ostr.write(" *")
- for line in self.comment_before.split('\n'):
+ for line in self.comment_before.split("\n"):
ostr.write(" ")
ostr.write(line)
- ostr.write('\n')
+ ostr.write("\n")
ostr.write(INDENT * indent)
ostr.write(" */")
ostr.write("\n")
@@ -51,7 +51,7 @@ def _comment_after_to_stream(self, ostr, indent):
if self.comment_after is None:
return
- lines = self.comment_after.split('\n')
+ lines = self.comment_after.split("\n")
if len(lines) < 2:
ostr.write(" // ")
@@ -65,7 +65,7 @@ def _comment_after_to_stream(self, ostr, indent):
for line in lines:
ostr.write(" ")
ostr.write(line)
- ostr.write('\n')
+ ostr.write("\n")
ostr.write(INDENT * indent)
ostr.write(" */")
ostr.write("\n")
@@ -116,7 +116,7 @@ def to_decl_stream(self, ostr, indent):
ostr.write(" ")
ostr.write(self.name)
- if self.modifier != 'static' and self.initializer is not None:
+ if self.modifier != "static" and self.initializer is not None:
ostr.write(" = ")
self.initializer.to_stream(ostr, indent)
@@ -124,7 +124,7 @@ def to_decl_stream(self, ostr, indent):
ostr.write("\n")
def to_defn_stream(self, ostr, indent):
- if self.modifier != 'static':
+ if self.modifier != "static":
return
self._comment_before_to_stream(ostr, indent)
@@ -162,7 +162,7 @@ def __init__(self):
self.name = None
self.namespace = None
- self.type = 'class'
+ self.type = "class"
self.public_entries = []
self.protected_entries = []
self.private_entries = []
@@ -174,7 +174,13 @@ def to_decl_stream(self, ostr, indent=0):
ostr.write(" {\n")
ostr.write(INDENT * indent)
- ostr.write("%s %s {\n" % (self.type, self.name,))
+ ostr.write(
+ "%s %s {\n"
+ % (
+ self.type,
+ self.name,
+ )
+ )
if len(self.public_entries) > 0:
ostr.write(INDENT * indent)
@@ -224,6 +230,7 @@ def to_defn_stream(self, ostr, indent=0):
if self.namespace is not None:
ostr.write("}\n")
+
def gen_cpp_class(cls, namespace=None, type_map=None):
if type_map is None:
type_map = dict()
@@ -240,8 +247,7 @@ def gen_cpp_class(cls, namespace=None, type_map=None):
for k, v in cls.get_flat_type_info(cls).items():
member = DataMember(
- "static", "const std::string",
- k, StringLiteral(v.Attributes.sub_name or k)
+ "static", "const std::string", k, StringLiteral(v.Attributes.sub_name or k)
)
member.comment_before = v.Annotations.doc
diff --git a/spyne/util/http.py b/spyne/util/http.py
index 0330f5fdb..1b93b148d 100644
--- a/spyne/util/http.py
+++ b/spyne/util/http.py
@@ -22,22 +22,17 @@
import sys
import time
-
-from email.message import EmailMessage
-from time import strftime
-from time import gmtime
from collections import deque
+from email.message import EmailMessage
+from time import gmtime, strftime
-from spyne.util import six
+COOKIE_MAX_AGE = sys.maxsize
-if six.PY2:
- COOKIE_MAX_AGE = sys.maxint
-else:
- COOKIE_MAX_AGE = sys.maxsize
# This is a modified version of twisted's addCookie
-def generate_cookie(k, v, max_age=None, domain=None, path=None,
- comment=None, secure=False):
+def generate_cookie(
+ k, v, max_age=None, domain=None, path=None, comment=None, secure=False
+):
"""Generate a HTTP response cookie. No sanity check whatsoever is done,
don't send anything other than ASCII.
@@ -50,19 +45,20 @@ def generate_cookie(k, v, max_age=None, domain=None, path=None,
:param secure: If true, appends 'Secure' to the cookie string.
"""
- if not six.PY2 and isinstance(v, bytes):
+ if isinstance(v, bytes):
v = v.decode("ascii")
- retval = deque(['%s=%s' % (k, v)])
+ retval = deque(["%s=%s" % (k, v)])
if max_age is not None:
retval.append("Max-Age=%d" % max_age)
assert time.time() < COOKIE_MAX_AGE
expires = time.time() + max_age
- expires = min(2<<30, expires) - 1 # FIXME
- retval.append("Expires=%s" % strftime("%a, %d %b %Y %H:%M:%S GMT",
- gmtime(expires)))
+ expires = min(2 << 30, expires) - 1 # FIXME
+ retval.append(
+ "Expires=%s" % strftime("%a, %d %b %Y %H:%M:%S GMT", gmtime(expires))
+ )
if domain is not None:
retval.append("Domain=%s" % domain)
if path is not None:
@@ -72,9 +68,10 @@ def generate_cookie(k, v, max_age=None, domain=None, path=None,
if secure:
retval.append("Secure")
- return '; '.join(retval)
+ return "; ".join(retval)
+
def parse_content_type_header(h):
msg = EmailMessage()
- msg['content-type'] = h
- return msg.get_content_type(), msg['content-type'].params
+ msg["content-type"] = h
+ return msg.get_content_type(), msg["content-type"].params
diff --git a/spyne/util/invregexp.py b/spyne/util/invregexp.py
index 1e7f1e52b..769ac8e89 100644
--- a/spyne/util/invregexp.py
+++ b/spyne/util/invregexp.py
@@ -1,4 +1,3 @@
-
#
# invRegex.py
#
@@ -42,20 +41,22 @@
__all__ = ["count", "invregexp"]
-from pyparsing import Combine
-from pyparsing import Literal
-from pyparsing import ParseFatalException
-from pyparsing import ParseResults
-from pyparsing import ParserElement
-from pyparsing import SkipTo
-from pyparsing import Suppress
-from pyparsing import Word
-from pyparsing import nums
-from pyparsing import oneOf
-from pyparsing import opAssoc
-from pyparsing import operatorPrecedence
-from pyparsing import printables
-from pyparsing import srange
+from pyparsing import (
+ Combine,
+ Literal,
+ ParseFatalException,
+ ParserElement,
+ ParseResults,
+ SkipTo,
+ Suppress,
+ Word,
+ nums,
+ oneOf,
+ opAssoc,
+ operatorPrecedence,
+ printables,
+ srange,
+)
class CharacterRangeEmitter(object):
@@ -65,15 +66,16 @@ def __init__(self, chars):
self.charset = "".join(seen.add(c) or c for c in chars if c not in seen)
def __str__(self):
- return '[' + self.charset + ']'
+ return "[" + self.charset + "]"
def __repr__(self):
- return '[' + self.charset + ']'
+ return "[" + self.charset + "]"
def make_generator(self):
def gen_chars():
for s in self.charset:
yield s
+
return gen_chars
@@ -86,6 +88,7 @@ def optional_gen():
yield ""
for s in self.expr.make_generator()():
yield s
+
return optional_gen
@@ -94,6 +97,7 @@ def make_generator(self):
def dot_gen():
for c in printables:
yield c
+
return dot_gen
@@ -111,6 +115,7 @@ def recurse_list(elist):
for s in elist[0].make_generator()():
for s2 in recurse_list(elist[1:]):
yield s + s2
+
if self.exprs:
for s in recurse_list(self.exprs):
yield s
@@ -178,7 +183,7 @@ def handle_literal(toks):
for t in toks:
if t[0] == "\\":
if t[1] == "t":
- lit += '\t'
+ lit += "\t"
else:
lit += t[1]
else:
@@ -195,7 +200,9 @@ def handle_macro(toks):
elif macroChar == "s":
return LiteralEmitter(" ")
else:
- raise ParseFatalException("", 0, "unsupported macro character (" + macroChar + ")")
+ raise ParseFatalException(
+ "", 0, "unsupported macro character (" + macroChar + ")"
+ )
def handle_sequence(toks):
@@ -211,6 +218,8 @@ def handle_alternative(toks):
_parser = None
+
+
def parser():
global _parser
if _parser is None:
@@ -218,29 +227,40 @@ def parser():
lbrack, rbrack, lbrace, rbrace, lparen, rparen = map(Literal, "[]{}()")
reMacro = Combine("\\" + oneOf(list("dws")))
- escapedChar = ~ reMacro + Combine("\\" + oneOf(list(printables)))
- reLiteralChar = "".join(c for c in printables if c not in r"\[]{}().*?+|") + " \t"
+ escapedChar = ~reMacro + Combine("\\" + oneOf(list(printables)))
+ reLiteralChar = (
+ "".join(c for c in printables if c not in r"\[]{}().*?+|") + " \t"
+ )
reRange = Combine(lbrack + SkipTo(rbrack, ignore=escapedChar) + rbrack)
- reLiteral = (escapedChar | oneOf(list(reLiteralChar)))
+ reLiteral = escapedChar | oneOf(list(reLiteralChar))
reDot = Literal(".")
repetition = (
- (lbrace + Word(nums).setResultsName("count") + rbrace) |
- (lbrace + Word(nums).setResultsName("minCount") + "," + Word(nums).setResultsName("maxCount") + rbrace) |
- oneOf(list("*+?"))
- )
+ (lbrace + Word(nums).setResultsName("count") + rbrace)
+ | (
+ lbrace
+ + Word(nums).setResultsName("minCount")
+ + ","
+ + Word(nums).setResultsName("maxCount")
+ + rbrace
+ )
+ | oneOf(list("*+?"))
+ )
reRange.setParseAction(handle_range)
reLiteral.setParseAction(handle_literal)
reMacro.setParseAction(handle_macro)
reDot.setParseAction(handle_dot)
- reTerm = (reLiteral | reRange | reMacro | reDot)
- reExpr = operatorPrecedence(reTerm, [
+ reTerm = reLiteral | reRange | reMacro | reDot
+ reExpr = operatorPrecedence(
+ reTerm,
+ [
(repetition, 1, opAssoc.LEFT, handle_repetition),
(None, 2, opAssoc.LEFT, handle_sequence),
- (Suppress('|'), 2, opAssoc.LEFT, handle_alternative),
- ])
+ (Suppress("|"), 2, opAssoc.LEFT, handle_alternative),
+ ],
+ )
_parser = reExpr
@@ -257,9 +277,9 @@ def count(gen):
def invregexp(regex):
"""Call this routine as a generator to return all the strings that
- match the input regular expression.
- for s in invregexp("[A-Z]{3}\d{3}"):
- print s
+ match the input regular expression.
+ for s in invregexp("[A-Z]{3}\d{3}"):
+ print s
"""
invReGenerator = GroupEmitter(parser().parseString(regex)).make_generator()
return invReGenerator()
@@ -296,14 +316,14 @@ def main():
A[cglmrstu]|B[aehikr]?|C[adeflmorsu]?|D[bsy]|E[rsu]|F[emr]?|G[ade]|H[efgos]?|I[nr]?|Kr?|L[airu]|M[dgnot]|N[abdeiop]?|Os?|P[abdmortu]?|R[abefghnu]|S[bcegimnr]?|T[abcehilm]|Uu[bhopqst]|U|V|W|Xe|Yb?|Z[nr]
(a|b)|(x|y)
(a|b) (x|y)
- """.split('\n')
+ """.split("\n")
for t in tests:
t = t.strip()
if not t:
continue
- print('-' * 50)
+ print("-" * 50)
print(t)
try:
print(count(invregexp(t)))
diff --git a/spyne/util/memo.py b/spyne/util/memo.py
index d64efb5e5..c53384946 100644
--- a/spyne/util/memo.py
+++ b/spyne/util/memo.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -26,13 +25,12 @@
behavior in a multithreaded environment, roll your own stuff.
"""
-
import logging
+
logger = logging.getLogger(__name__)
import threading
-
MEMOIZATION_STATS_LOG_INTERVAL = 60.0
@@ -56,16 +54,19 @@ def _log_func(func):
def start_memoization_stats_logger(func=None):
- logger.info("Enabling @memoize statistics every %d second(s).",
- MEMOIZATION_STATS_LOG_INTERVAL)
+ logger.info(
+ "Enabling @memoize statistics every %d second(s).",
+ MEMOIZATION_STATS_LOG_INTERVAL,
+ )
if func is None:
_log_all()
else:
_log_func(func)
- t = threading.Timer(MEMOIZATION_STATS_LOG_INTERVAL,
- start_memoization_stats_logger, (func,))
+ t = threading.Timer(
+ MEMOIZATION_STATS_LOG_INTERVAL, start_memoization_stats_logger, (func,)
+ )
t.daemon = True
t.start()
@@ -113,7 +114,7 @@ def __init__(self, func):
memoize.registry.append(self)
def __call__(self, *args, **kwargs):
- if not hasattr(self, 'memo'):
+ if not hasattr(self, "memo"):
value = self.func(*args, **kwargs)
self.memo = value
return value
@@ -130,8 +131,7 @@ def memoize_ignore(values):
but the result of `add(5, 5)` (=10) is.
"""
- assert iter(values), \
- "memoize_ignore requires an iterable of values to ignore"
+ assert iter(values), "memoize_ignore requires an iterable of values to ignore"
class _memoize_ignored(memoize):
def __call__(self, *args, **kwargs):
@@ -176,5 +176,6 @@ class memoize_id(memoize):
types. It works on id()'s of objects instead."""
def get_key(self, args, kwargs):
- return tuple([id(a) for a in args]), \
- tuple([(k, id(v)) for k, v in kwargs.items()])
+ return tuple([id(a) for a in args]), tuple(
+ [(k, id(v)) for k, v in kwargs.items()]
+ )
diff --git a/spyne/util/meta.py b/spyne/util/meta.py
index 81f8da025..21d8e1b00 100644
--- a/spyne/util/meta.py
+++ b/spyne/util/meta.py
@@ -21,9 +21,8 @@
:attr:`spyne.model.complex.ComplexModelBase.Attributes.declare_order`
"""
-import sys
import inspect
-
+import sys
from functools import wraps
from itertools import chain
from warnings import warn
@@ -40,11 +39,7 @@ class AttributeNotFoundException(Exception):
class Prepareable(type):
- """Implement __prepare__ for Python 2.
-
- This class is used in Python 2 and Python 3 to support `six.add_metaclass`
- decorator that populates attributes of resulting class from plain unordered
- attributes dict of decorated class.
+ """Implement __prepare__ to support ordered class attributes.
Based on https://gist.github.com/DasIch/5562625
"""
@@ -59,8 +54,9 @@ def preparing_constructor(cls, name, bases, attributes):
# Don't bother with this shit unless the user *explicitly* asked for
# it
for c in chain(bases, [cls]):
- if hasattr(c,'Attributes') and not \
- (c.Attributes.declare_order in (None, 'random')):
+ if hasattr(c, "Attributes") and not (
+ c.Attributes.declare_order in (None, "random")
+ ):
break
else:
return constructor(cls, name, bases, attributes)
@@ -90,24 +86,26 @@ def preparing_constructor(cls, name, bases, attributes):
current_frame = current_frame.f_back
else:
raise ClassNotFoundException(
- "Can't find class declaration in any frame")
+ "Can't find class declaration in any frame"
+ )
- def get_index(attribute_name,
- _names=class_declaration.co_names):
+ def get_index(attribute_name, _names=class_declaration.co_names):
try:
return _names.index(attribute_name)
except ValueError:
- if attribute_name.startswith('_'):
+ if attribute_name.startswith("_"):
# we don't care about the order of magic and non
# public attributes
return 0
else:
- msg = ("Can't find {0} in {1} class declaration. "
- .format(attribute_name,
- class_declaration.co_name))
- msg += ("HINT: use spyne.util.odict.odict for "
- "class attributes if you populate them"
- " dynamically.")
+ msg = "Can't find {0} in {1} class declaration. ".format(
+ attribute_name, class_declaration.co_name
+ )
+ msg += (
+ "HINT: use spyne.util.odict.odict for "
+ "class attributes if you populate them"
+ " dynamically."
+ )
raise AttributeNotFoundException(msg)
by_appearance = sorted(
@@ -121,19 +119,25 @@ def get_index(attribute_name,
new_cls = constructor(cls, name, bases, namespace)
found_module = inspect.getmodule(class_declaration)
- assert found_module is not None, (
- 'Module is not found for class_declaration {0}, name {1}'
- .format(class_declaration, name))
- assert found_module.__name__ == new_cls.__module__, (
- 'Found wrong class declaration of {0}: {1} != {2}.'
- .format(name, found_module.__name__, new_cls.__module__))
+ assert (
+ found_module is not None
+ ), "Module is not found for class_declaration {0}, name {1}".format(
+ class_declaration, name
+ )
+ assert (
+ found_module.__name__ == new_cls.__module__
+ ), "Found wrong class declaration of {0}: {1} != {2}.".format(
+ name, found_module.__name__, new_cls.__module__
+ )
return new_cls
try:
attributes["__new__"] = wraps(constructor)(preparing_constructor)
except:
- warn("Wrapping class initializer failed. This is normal "
- "when running under Nuitka")
+ warn(
+ "Wrapping class initializer failed. This is normal "
+ "when running under Nuitka"
+ )
return type.__new__(cls, name, bases, attributes)
diff --git a/spyne/util/odict.py b/spyne/util/odict.py
index d8b996ded..1b99f3bce 100644
--- a/spyne/util/odict.py
+++ b/spyne/util/odict.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -57,10 +56,12 @@ def __setitem__(self, key, val):
super(odict, self).__setitem__(key, val)
assert len(self.__list) == super(odict, self).__len__(), (
- repr(self.__list), super(odict, self).__repr__())
+ repr(self.__list),
+ super(odict, self).__repr__(),
+ )
def __repr__(self):
- return "{%s}" % ','.join(["%r: %r" % (k, v) for k, v in self.items()])
+ return "{%s}" % ",".join(["%r: %r" % (k, v) for k, v in self.items()])
def __str__(self):
return repr(self)
@@ -75,7 +76,7 @@ def __iter__(self):
def __delitem__(self, key):
if not isinstance(key, int):
super(odict, self).__delitem__(key)
- key = self.__list.index(key) # ouch.
+ key = self.__list.index(key) # ouch.
else:
super(odict, self).__delitem__(self.__list[key])
del self.__list[key]
@@ -87,7 +88,7 @@ def __add__(self, other):
def items(self):
retval = []
for k in self.__list:
- retval.append( (k, super(odict, self).__getitem__(k)) )
+ retval.append((k, super(odict, self).__getitem__(k)))
return retval
def iteritems(self):
diff --git a/spyne/util/oset.py b/spyne/util/oset.py
index 03e7c591e..0028ab1a3 100644
--- a/spyne/util/oset.py
+++ b/spyne/util/oset.py
@@ -1,19 +1,20 @@
# http://code.activestate.com/recipes/576694/
-from spyne.util.six.moves.collections_abc import MutableSet
+from collections.abc import MutableSet
KEY, PREV, NEXT = list(range(3))
"""This module contains an ordered set implementation from
http://code.activestate.com/recipes/576694/ """
+
class oset(MutableSet):
"""An ordered set implementation."""
def __init__(self, iterable=None):
self.end = end = []
- end += [None, end, end] # sentinel node for doubly linked list
- self.map = {} # key --> [key, prev, next]
+ end += [None, end, end] # sentinel node for doubly linked list
+ self.map = {} # key --> [key, prev, next]
if iterable is not None:
self |= iterable
@@ -58,15 +59,15 @@ def __reversed__(self):
def pop(self, last=True):
if not self:
- raise KeyError('set is empty')
+ raise KeyError("set is empty")
key = next(reversed(self)) if last else next(iter(self))
self.discard(key)
return key
def __repr__(self):
if not self:
- return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, list(self))
+ return "%s()" % (self.__class__.__name__,)
+ return "%s(%r)" % (self.__class__.__name__, list(self))
def __eq__(self, other):
if isinstance(other, oset):
@@ -77,15 +78,16 @@ def __eq__(self, other):
def back(self):
return self.end[1][0]
-if __name__ == '__main__':
- print((oset('abracadabra')))
+
+if __name__ == "__main__":
+ print((oset("abracadabra")))
stuff = oset()
stuff.add(1)
print(stuff)
stuff.add(1)
print(stuff)
- print((oset('simsalabim')))
- o = oset('abcde')
+ print((oset("simsalabim")))
+ o = oset("abcde")
print(o)
print(o.end)
diff --git a/spyne/util/protocol.py b/spyne/util/protocol.py
index 4ae305c85..3f702afc9 100644
--- a/spyne/util/protocol.py
+++ b/spyne/util/protocol.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
diff --git a/spyne/util/resource.py b/spyne/util/resource.py
index bde03e8a6..10152b523 100644
--- a/spyne/util/resource.py
+++ b/spyne/util/resource.py
@@ -35,16 +35,16 @@ def get_resource_path(ns, fn):
def get_resource_file(ns, fn):
- return open(get_resource_path(ns, fn), 'rb')
+ return open(get_resource_path(ns, fn), "rb")
def get_resource_file_contents(ns, fn, enc=None):
resfn = get_resource_path(ns, fn)
if enc is None:
- return open(resfn, 'rb').read()
+ return open(resfn, "rb").read()
else:
- return open(resfn, 'rb').read().decode(enc)
+ return open(resfn, "rb").read().decode(enc)
def parse_xml_resource(ns, fn):
@@ -66,7 +66,8 @@ def parse_html_resource(ns, fn):
def parse_cloth_resource(ns, fn):
from lxml import html
- retval = html.fragment_fromstring(get_resource_file_contents(ns, fn),
- create_parent='spyne-root')
- retval.attrib['spyne-tagbag'] = ''
+ retval = html.fragment_fromstring(
+ get_resource_file_contents(ns, fn), create_parent="spyne-root"
+ )
+ retval.attrib["spyne-tagbag"] = ""
return retval
diff --git a/spyne/util/simple.py b/spyne/util/simple.py
index 164be684d..0bc05de29 100644
--- a/spyne/util/simple.py
+++ b/spyne/util/simple.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -20,12 +19,12 @@
"""Contains functions that implement the most common protocol and transport
combinations"""
-
from spyne.application import Application
-def wsgi_soap11_application(services, tns='spyne.simple.soap', validator=None,
- name=None):
+def wsgi_soap11_application(
+ services, tns="spyne.simple.soap", validator=None, name=None
+):
"""Wraps `services` argument inside a WsgiApplication that uses Soap 1.1 for
both input and output protocols.
"""
@@ -33,17 +32,24 @@ def wsgi_soap11_application(services, tns='spyne.simple.soap', validator=None,
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication
- application = Application(services, tns, name=name,
- in_protocol=Soap11(validator=validator), out_protocol=Soap11())
+ application = Application(
+ services,
+ tns,
+ name=name,
+ in_protocol=Soap11(validator=validator),
+ out_protocol=Soap11(),
+ )
return WsgiApplication(application)
+
wsgi_soap_application = wsgi_soap11_application
"""DEPRECATED! Use :func:`wsgi_soap11_application` instead."""
-def pyramid_soap11_application(services, tns='spyne.simple.soap',
- validator=None, name=None):
+def pyramid_soap11_application(
+ services, tns="spyne.simple.soap", validator=None, name=None
+):
"""Wraps `services` argument inside a PyramidApplication that uses Soap 1.1
for both input and output protocols.
"""
@@ -51,7 +57,12 @@ def pyramid_soap11_application(services, tns='spyne.simple.soap',
from spyne.protocol.soap import Soap11
from spyne.server.pyramid import PyramidApplication
- application = Application(services, tns, name=name,
- in_protocol=Soap11(validator=validator), out_protocol=Soap11())
+ application = Application(
+ services,
+ tns,
+ name=name,
+ in_protocol=Soap11(validator=validator),
+ out_protocol=Soap11(),
+ )
return PyramidApplication(application)
diff --git a/spyne/util/six.py b/spyne/util/six.py
deleted file mode 100644
index 84871a9c7..000000000
--- a/spyne/util/six.py
+++ /dev/null
@@ -1,1003 +0,0 @@
-# Copyright (c) 2010-2020 Benjamin Peterson
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-"""Utilities for writing code that runs on Python 2 and 3"""
-
-from __future__ import absolute_import
-
-import functools
-import itertools
-import operator
-import sys
-import types
-
-__author__ = "Benjamin Peterson "
-__version__ = "1.16.0"
-
-
-# Useful for very coarse version differentiation.
-PY2 = sys.version_info[0] == 2
-PY3 = sys.version_info[0] == 3
-PY34 = sys.version_info[0:2] >= (3, 4)
-
-if PY3:
- string_types = str,
- integer_types = int,
- class_types = type,
- text_type = str
- binary_type = bytes
-
- MAXSIZE = sys.maxsize
-else:
- string_types = basestring,
- integer_types = (int, long)
- class_types = (type, types.ClassType)
- text_type = unicode
- binary_type = str
-
- if sys.platform.startswith("java"):
- # Jython always uses 32 bits.
- MAXSIZE = int((1 << 31) - 1)
- else:
- # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
- class X(object):
-
- def __len__(self):
- return 1 << 31
- try:
- len(X())
- except OverflowError:
- # 32-bit
- MAXSIZE = int((1 << 31) - 1)
- else:
- # 64-bit
- MAXSIZE = int((1 << 63) - 1)
- del X
-
-if PY34:
- from importlib.util import spec_from_loader
-else:
- spec_from_loader = None
-
-
-def _add_doc(func, doc):
- """Add documentation to a function."""
- func.__doc__ = doc
-
-
-def _import_module(name):
- """Import module, returning the module after the last dot."""
- __import__(name)
- return sys.modules[name]
-
-
-class _LazyDescr(object):
-
- def __init__(self, name):
- self.name = name
-
- def __get__(self, obj, tp):
- result = self._resolve()
- setattr(obj, self.name, result) # Invokes __set__.
- try:
- # This is a bit ugly, but it avoids running this again by
- # removing this descriptor.
- delattr(obj.__class__, self.name)
- except AttributeError:
- pass
- return result
-
-
-class MovedModule(_LazyDescr):
-
- def __init__(self, name, old, new=None):
- super(MovedModule, self).__init__(name)
- if PY3:
- if new is None:
- new = name
- self.mod = new
- else:
- self.mod = old
-
- def _resolve(self):
- return _import_module(self.mod)
-
- def __getattr__(self, attr):
- _module = self._resolve()
- value = getattr(_module, attr)
- setattr(self, attr, value)
- return value
-
-
-class _LazyModule(types.ModuleType):
-
- def __init__(self, name):
- super(_LazyModule, self).__init__(name)
- self.__doc__ = self.__class__.__doc__
-
- def __dir__(self):
- attrs = ["__doc__", "__name__"]
- attrs += [attr.name for attr in self._moved_attributes]
- return attrs
-
- # Subclasses should override this
- _moved_attributes = []
-
-
-class MovedAttribute(_LazyDescr):
-
- def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
- super(MovedAttribute, self).__init__(name)
- if PY3:
- if new_mod is None:
- new_mod = name
- self.mod = new_mod
- if new_attr is None:
- if old_attr is None:
- new_attr = name
- else:
- new_attr = old_attr
- self.attr = new_attr
- else:
- self.mod = old_mod
- if old_attr is None:
- old_attr = name
- self.attr = old_attr
-
- def _resolve(self):
- module = _import_module(self.mod)
- return getattr(module, self.attr)
-
-
-class _SixMetaPathImporter(object):
-
- """
- A meta path importer to import six.moves and its submodules.
-
- This class implements a PEP302 finder and loader. It should be compatible
- with Python 2.5 and all existing versions of Python3
- """
-
- def __init__(self, six_module_name):
- self.name = six_module_name
- self.known_modules = {}
-
- def _add_module(self, mod, *fullnames):
- for fullname in fullnames:
- self.known_modules[self.name + "." + fullname] = mod
-
- def _get_module(self, fullname):
- return self.known_modules[self.name + "." + fullname]
-
- def find_module(self, fullname, path=None):
- if fullname in self.known_modules:
- return self
- return None
-
- def find_spec(self, fullname, path, target=None):
- if fullname in self.known_modules:
- return spec_from_loader(fullname, self)
- return None
-
- def __get_module(self, fullname):
- try:
- return self.known_modules[fullname]
- except KeyError:
- raise ImportError("This loader does not know module " + fullname)
-
- def load_module(self, fullname):
- try:
- # in case of a reload
- return sys.modules[fullname]
- except KeyError:
- pass
- mod = self.__get_module(fullname)
- if isinstance(mod, MovedModule):
- mod = mod._resolve()
- else:
- mod.__loader__ = self
- sys.modules[fullname] = mod
- return mod
-
- def is_package(self, fullname):
- """
- Return true, if the named module is a package.
-
- We need this method to get correct spec objects with
- Python 3.4 (see PEP451)
- """
- return hasattr(self.__get_module(fullname), "__path__")
-
- def get_code(self, fullname):
- """Return None
-
- Required, if is_package is implemented"""
- self.__get_module(fullname) # eventually raises ImportError
- return None
- get_source = get_code # same as get_code
-
- def create_module(self, spec):
- return self.load_module(spec.name)
-
- def exec_module(self, module):
- pass
-
-_importer = _SixMetaPathImporter(__name__)
-
-
-class _MovedItems(_LazyModule):
-
- """Lazy loading of moved objects"""
- __path__ = [] # mark as package
-
-
-_moved_attributes = [
- MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
- MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
- MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
- MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
- MovedAttribute("intern", "__builtin__", "sys"),
- MovedAttribute("map", "itertools", "builtins", "imap", "map"),
- MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
- MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
- MovedAttribute("getoutput", "commands", "subprocess"),
- MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
- MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
- MovedAttribute("reduce", "__builtin__", "functools"),
- MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
- MovedAttribute("StringIO", "StringIO", "io"),
- MovedAttribute("UserDict", "UserDict", "collections", "IterableUserDict", "UserDict"),
- MovedAttribute("UserList", "UserList", "collections"),
- MovedAttribute("UserString", "UserString", "collections"),
- MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
- MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
- MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
- MovedModule("builtins", "__builtin__"),
- MovedModule("configparser", "ConfigParser"),
- MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"),
- MovedModule("copyreg", "copy_reg"),
- MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
- MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
- MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"),
- MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
- MovedModule("http_cookies", "Cookie", "http.cookies"),
- MovedModule("html_entities", "htmlentitydefs", "html.entities"),
- MovedModule("html_parser", "HTMLParser", "html.parser"),
- MovedModule("http_client", "httplib", "http.client"),
- MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
- MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
- MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
- MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
- MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
- MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
- MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
- MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
- MovedModule("cPickle", "cPickle", "pickle"),
- MovedModule("queue", "Queue"),
- MovedModule("reprlib", "repr"),
- MovedModule("socketserver", "SocketServer"),
- MovedModule("_thread", "thread", "_thread"),
- MovedModule("tkinter", "Tkinter"),
- MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
- MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
- MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
- MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
- MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
- MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
- MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
- MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
- MovedModule("tkinter_colorchooser", "tkColorChooser",
- "tkinter.colorchooser"),
- MovedModule("tkinter_commondialog", "tkCommonDialog",
- "tkinter.commondialog"),
- MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
- MovedModule("tkinter_font", "tkFont", "tkinter.font"),
- MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
- MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
- "tkinter.simpledialog"),
- MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
- MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
- MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
- MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
- MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
- MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
-]
-# Add windows specific modules.
-if sys.platform == "win32":
- _moved_attributes += [
- MovedModule("winreg", "_winreg"),
- ]
-
-for attr in _moved_attributes:
- setattr(_MovedItems, attr.name, attr)
- if isinstance(attr, MovedModule):
- _importer._add_module(attr, "moves." + attr.name)
-del attr
-
-_MovedItems._moved_attributes = _moved_attributes
-
-moves = _MovedItems(__name__ + ".moves")
-_importer._add_module(moves, "moves")
-
-
-class Module_six_moves_urllib_parse(_LazyModule):
-
- """Lazy loading of moved objects in six.moves.urllib_parse"""
-
-
-_urllib_parse_moved_attributes = [
- MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
- MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
- MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
- MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
- MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
- MovedAttribute("urljoin", "urlparse", "urllib.parse"),
- MovedAttribute("urlparse", "urlparse", "urllib.parse"),
- MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
- MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
- MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
- MovedAttribute("quote", "urllib", "urllib.parse"),
- MovedAttribute("quote_plus", "urllib", "urllib.parse"),
- MovedAttribute("unquote", "urllib", "urllib.parse"),
- MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
- MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),
- MovedAttribute("urlencode", "urllib", "urllib.parse"),
- MovedAttribute("splitquery", "urllib", "urllib.parse"),
- MovedAttribute("splittag", "urllib", "urllib.parse"),
- MovedAttribute("splituser", "urllib", "urllib.parse"),
- MovedAttribute("splitvalue", "urllib", "urllib.parse"),
- MovedAttribute("splittype", "urllib", "urllib.parse"),
- MovedAttribute("splithost", "urllib", "urllib.parse"),
- MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
- MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
- MovedAttribute("uses_params", "urlparse", "urllib.parse"),
- MovedAttribute("uses_query", "urlparse", "urllib.parse"),
- MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
-]
-for attr in _urllib_parse_moved_attributes:
- setattr(Module_six_moves_urllib_parse, attr.name, attr)
-del attr
-
-Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
-
-_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
- "moves.urllib_parse", "moves.urllib.parse")
-
-
-class Module_six_moves_urllib_error(_LazyModule):
-
- """Lazy loading of moved objects in six.moves.urllib_error"""
-
-
-_urllib_error_moved_attributes = [
- MovedAttribute("URLError", "urllib2", "urllib.error"),
- MovedAttribute("HTTPError", "urllib2", "urllib.error"),
- MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
-]
-for attr in _urllib_error_moved_attributes:
- setattr(Module_six_moves_urllib_error, attr.name, attr)
-del attr
-
-Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
-
-_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
- "moves.urllib_error", "moves.urllib.error")
-
-
-class Module_six_moves_urllib_request(_LazyModule):
-
- """Lazy loading of moved objects in six.moves.urllib_request"""
-
-
-_urllib_request_moved_attributes = [
- MovedAttribute("urlopen", "urllib2", "urllib.request"),
- MovedAttribute("install_opener", "urllib2", "urllib.request"),
- MovedAttribute("build_opener", "urllib2", "urllib.request"),
- MovedAttribute("pathname2url", "urllib", "urllib.request"),
- MovedAttribute("url2pathname", "urllib", "urllib.request"),
- MovedAttribute("getproxies", "urllib", "urllib.request"),
- MovedAttribute("Request", "urllib2", "urllib.request"),
- MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
- MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
- MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
- MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
- MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
- MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
- MovedAttribute("FileHandler", "urllib2", "urllib.request"),
- MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
- MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
- MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
- MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
- MovedAttribute("urlretrieve", "urllib", "urllib.request"),
- MovedAttribute("urlcleanup", "urllib", "urllib.request"),
- MovedAttribute("URLopener", "urllib", "urllib.request"),
- MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
- MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
- MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
- MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
-]
-for attr in _urllib_request_moved_attributes:
- setattr(Module_six_moves_urllib_request, attr.name, attr)
-del attr
-
-Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
-
-_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
- "moves.urllib_request", "moves.urllib.request")
-
-
-class Module_six_moves_urllib_response(_LazyModule):
-
- """Lazy loading of moved objects in six.moves.urllib_response"""
-
-
-_urllib_response_moved_attributes = [
- MovedAttribute("addbase", "urllib", "urllib.response"),
- MovedAttribute("addclosehook", "urllib", "urllib.response"),
- MovedAttribute("addinfo", "urllib", "urllib.response"),
- MovedAttribute("addinfourl", "urllib", "urllib.response"),
-]
-for attr in _urllib_response_moved_attributes:
- setattr(Module_six_moves_urllib_response, attr.name, attr)
-del attr
-
-Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
-
-_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
- "moves.urllib_response", "moves.urllib.response")
-
-
-class Module_six_moves_urllib_robotparser(_LazyModule):
-
- """Lazy loading of moved objects in six.moves.urllib_robotparser"""
-
-
-_urllib_robotparser_moved_attributes = [
- MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
-]
-for attr in _urllib_robotparser_moved_attributes:
- setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
-del attr
-
-Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
-
-_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
- "moves.urllib_robotparser", "moves.urllib.robotparser")
-
-
-class Module_six_moves_urllib(types.ModuleType):
-
- """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
- __path__ = [] # mark as package
- parse = _importer._get_module("moves.urllib_parse")
- error = _importer._get_module("moves.urllib_error")
- request = _importer._get_module("moves.urllib_request")
- response = _importer._get_module("moves.urllib_response")
- robotparser = _importer._get_module("moves.urllib_robotparser")
-
- def __dir__(self):
- return ['parse', 'error', 'request', 'response', 'robotparser']
-
-_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
- "moves.urllib")
-
-
-def add_move(move):
- """Add an item to six.moves."""
- setattr(_MovedItems, move.name, move)
-
-
-def remove_move(name):
- """Remove item from six.moves."""
- try:
- delattr(_MovedItems, name)
- except AttributeError:
- try:
- del moves.__dict__[name]
- except KeyError:
- raise AttributeError("no such move, %r" % (name,))
-
-
-if PY3:
- _meth_func = "__func__"
- _meth_self = "__self__"
-
- _func_closure = "__closure__"
- _func_code = "__code__"
- _func_defaults = "__defaults__"
- _func_globals = "__globals__"
- _func_name = "__name__"
-else:
- _meth_func = "im_func"
- _meth_self = "im_self"
-
- _func_closure = "func_closure"
- _func_code = "func_code"
- _func_defaults = "func_defaults"
- _func_globals = "func_globals"
- _func_name = "func_name"
-
-
-try:
- advance_iterator = next
-except NameError:
- def advance_iterator(it):
- return it.next()
-next = advance_iterator
-
-
-try:
- callable = callable
-except NameError:
- def callable(obj):
- return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
-
-
-if PY3:
- def get_unbound_function(unbound):
- return unbound
-
- create_bound_method = types.MethodType
-
- def create_unbound_method(func, cls):
- return func
-
- Iterator = object
-else:
- def get_unbound_function(unbound):
- return unbound.im_func
-
- def create_bound_method(func, obj):
- return types.MethodType(func, obj, obj.__class__)
-
- def create_unbound_method(func, cls):
- return types.MethodType(func, None, cls)
-
- class Iterator(object):
-
- def next(self):
- return type(self).__next__(self)
-
- callable = callable
-_add_doc(get_unbound_function,
- """Get the function out of a possibly unbound function""")
-
-
-get_method_function = operator.attrgetter(_meth_func)
-get_method_self = operator.attrgetter(_meth_self)
-get_function_closure = operator.attrgetter(_func_closure)
-get_function_code = operator.attrgetter(_func_code)
-get_function_defaults = operator.attrgetter(_func_defaults)
-get_function_globals = operator.attrgetter(_func_globals)
-get_function_name = operator.attrgetter(_func_name)
-
-
-if PY3:
- def iterkeys(d, **kw):
- return iter(d.keys(**kw))
-
- def itervalues(d, **kw):
- return iter(d.values(**kw))
-
- def iteritems(d, **kw):
- return iter(d.items(**kw))
-
- def iterlists(d, **kw):
- return iter(d.lists(**kw))
-
- viewkeys = operator.methodcaller("keys")
-
- viewvalues = operator.methodcaller("values")
-
- viewitems = operator.methodcaller("items")
-else:
- def iterkeys(d, **kw):
- return d.iterkeys(**kw)
-
- def itervalues(d, **kw):
- return d.itervalues(**kw)
-
- def iteritems(d, **kw):
- return d.iteritems(**kw)
-
- def iterlists(d, **kw):
- return d.iterlists(**kw)
-
- viewkeys = operator.methodcaller("viewkeys")
-
- viewvalues = operator.methodcaller("viewvalues")
-
- viewitems = operator.methodcaller("viewitems")
-
-_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
-_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
-_add_doc(iteritems,
- "Return an iterator over the (key, value) pairs of a dictionary.")
-_add_doc(iterlists,
- "Return an iterator over the (key, [values]) pairs of a dictionary.")
-
-
-if PY3:
- def b(s):
- return s.encode("latin-1")
-
- def u(s):
- return s
- unichr = chr
- import struct
- int2byte = struct.Struct(">B").pack
- del struct
- byte2int = operator.itemgetter(0)
- indexbytes = operator.getitem
- iterbytes = iter
- import io
- StringIO = io.StringIO
- BytesIO = io.BytesIO
- del io
- _assertCountEqual = "assertCountEqual"
- if sys.version_info[1] <= 1:
- _assertRaisesRegex = "assertRaisesRegexp"
- _assertRegex = "assertRegexpMatches"
- _assertNotRegex = "assertNotRegexpMatches"
- else:
- _assertRaisesRegex = "assertRaisesRegex"
- _assertRegex = "assertRegex"
- _assertNotRegex = "assertNotRegex"
-else:
- def b(s):
- return s
- # Workaround for standalone backslash
-
- def u(s):
- return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
- unichr = unichr
- int2byte = chr
-
- def byte2int(bs):
- return ord(bs[0])
-
- def indexbytes(buf, i):
- return ord(buf[i])
- iterbytes = functools.partial(itertools.imap, ord)
- import StringIO
- StringIO = BytesIO = StringIO.StringIO
- _assertCountEqual = "assertItemsEqual"
- _assertRaisesRegex = "assertRaisesRegexp"
- _assertRegex = "assertRegexpMatches"
- _assertNotRegex = "assertNotRegexpMatches"
-_add_doc(b, """Byte literal""")
-_add_doc(u, """Text literal""")
-
-
-def assertCountEqual(self, *args, **kwargs):
- return getattr(self, _assertCountEqual)(*args, **kwargs)
-
-
-def assertRaisesRegex(self, *args, **kwargs):
- return getattr(self, _assertRaisesRegex)(*args, **kwargs)
-
-
-def assertRegex(self, *args, **kwargs):
- return getattr(self, _assertRegex)(*args, **kwargs)
-
-
-def assertNotRegex(self, *args, **kwargs):
- return getattr(self, _assertNotRegex)(*args, **kwargs)
-
-
-if PY3:
- exec_ = getattr(moves.builtins, "exec")
-
- def reraise(tp, value, tb=None):
- try:
- if value is None:
- value = tp()
- if value.__traceback__ is not tb:
- raise value.with_traceback(tb)
- raise value
- finally:
- value = None
- tb = None
-
-else:
- def exec_(_code_, _globs_=None, _locs_=None):
- """Execute code in a namespace."""
- if _globs_ is None:
- frame = sys._getframe(1)
- _globs_ = frame.f_globals
- if _locs_ is None:
- _locs_ = frame.f_locals
- del frame
- elif _locs_ is None:
- _locs_ = _globs_
- exec("""exec _code_ in _globs_, _locs_""")
-
- exec_("""def reraise(tp, value, tb=None):
- try:
- raise tp, value, tb
- finally:
- tb = None
-""")
-
-
-if sys.version_info[:2] > (3,):
- exec_("""def raise_from(value, from_value):
- try:
- raise value from from_value
- finally:
- value = None
-""")
-else:
- def raise_from(value, from_value):
- raise value
-
-
-print_ = getattr(moves.builtins, "print", None)
-if print_ is None:
- def print_(*args, **kwargs):
- """The new-style print function for Python 2.4 and 2.5."""
- fp = kwargs.pop("file", sys.stdout)
- if fp is None:
- return
-
- def write(data):
- if not isinstance(data, basestring):
- data = str(data)
- # If the file has an encoding, encode unicode with it.
- if (isinstance(fp, file) and
- isinstance(data, unicode) and
- fp.encoding is not None):
- errors = getattr(fp, "errors", None)
- if errors is None:
- errors = "strict"
- data = data.encode(fp.encoding, errors)
- fp.write(data)
- want_unicode = False
- sep = kwargs.pop("sep", None)
- if sep is not None:
- if isinstance(sep, unicode):
- want_unicode = True
- elif not isinstance(sep, str):
- raise TypeError("sep must be None or a string")
- end = kwargs.pop("end", None)
- if end is not None:
- if isinstance(end, unicode):
- want_unicode = True
- elif not isinstance(end, str):
- raise TypeError("end must be None or a string")
- if kwargs:
- raise TypeError("invalid keyword arguments to print()")
- if not want_unicode:
- for arg in args:
- if isinstance(arg, unicode):
- want_unicode = True
- break
- if want_unicode:
- newline = unicode("\n")
- space = unicode(" ")
- else:
- newline = "\n"
- space = " "
- if sep is None:
- sep = space
- if end is None:
- end = newline
- for i, arg in enumerate(args):
- if i:
- write(sep)
- write(arg)
- write(end)
-if sys.version_info[:2] < (3, 3):
- _print = print_
-
- def print_(*args, **kwargs):
- fp = kwargs.get("file", sys.stdout)
- flush = kwargs.pop("flush", False)
- _print(*args, **kwargs)
- if flush and fp is not None:
- fp.flush()
-
-_add_doc(reraise, """Reraise an exception.""")
-
-if sys.version_info[0:2] < (3, 4):
- # This does exactly the same what the :func:`py3:functools.update_wrapper`
- # function does on Python versions after 3.2. It sets the ``__wrapped__``
- # attribute on ``wrapper`` object and it doesn't raise an error if any of
- # the attributes mentioned in ``assigned`` and ``updated`` are missing on
- # ``wrapped`` object.
- def _update_wrapper(wrapper, wrapped,
- assigned=functools.WRAPPER_ASSIGNMENTS,
- updated=functools.WRAPPER_UPDATES):
- for attr in assigned:
- try:
- value = getattr(wrapped, attr)
- except AttributeError:
- continue
- else:
- setattr(wrapper, attr, value)
- for attr in updated:
- getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
- wrapper.__wrapped__ = wrapped
- return wrapper
- _update_wrapper.__doc__ = functools.update_wrapper.__doc__
-
- def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
- updated=functools.WRAPPER_UPDATES):
- return functools.partial(_update_wrapper, wrapped=wrapped,
- assigned=assigned, updated=updated)
- wraps.__doc__ = functools.wraps.__doc__
-
-else:
- wraps = functools.wraps
-
-
-def with_metaclass(meta, *bases):
- """Create a base class with a metaclass."""
- # This requires a bit of explanation: the basic idea is to make a dummy
- # metaclass for one level of class instantiation that replaces itself with
- # the actual metaclass.
- class metaclass(type):
-
- def __new__(cls, name, this_bases, d):
- if sys.version_info[:2] >= (3, 7):
- # This version introduced PEP 560 that requires a bit
- # of extra care (we mimic what is done by __build_class__).
- resolved_bases = types.resolve_bases(bases)
- if resolved_bases is not bases:
- d['__orig_bases__'] = bases
- else:
- resolved_bases = bases
- return meta(name, resolved_bases, d)
-
- @classmethod
- def __prepare__(cls, name, this_bases):
- return meta.__prepare__(name, bases)
- return type.__new__(metaclass, 'temporary_class', (), {})
-
-
-def add_metaclass(metaclass):
- """Class decorator for creating a class with a metaclass."""
- def wrapper(cls):
- orig_vars = cls.__dict__.copy()
- slots = orig_vars.get('__slots__')
- if slots is not None:
- if isinstance(slots, str):
- slots = [slots]
- for slots_var in slots:
- orig_vars.pop(slots_var)
- orig_vars.pop('__dict__', None)
- orig_vars.pop('__weakref__', None)
- if hasattr(cls, '__qualname__'):
- orig_vars['__qualname__'] = cls.__qualname__
- return metaclass(cls.__name__, cls.__bases__, orig_vars)
- return wrapper
-
-
-def ensure_binary(s, encoding='utf-8', errors='strict'):
- """Coerce **s** to six.binary_type.
-
- For Python 2:
- - `unicode` -> encoded to `str`
- - `str` -> `str`
-
- For Python 3:
- - `str` -> encoded to `bytes`
- - `bytes` -> `bytes`
- """
- if isinstance(s, binary_type):
- return s
- if isinstance(s, text_type):
- return s.encode(encoding, errors)
- raise TypeError("not expecting type '%s'" % type(s))
-
-
-def ensure_str(s, encoding='utf-8', errors='strict'):
- """Coerce *s* to `str`.
-
- For Python 2:
- - `unicode` -> encoded to `str`
- - `str` -> `str`
-
- For Python 3:
- - `str` -> `str`
- - `bytes` -> decoded to `str`
- """
- # Optimization: Fast return for the common case.
- if type(s) is str:
- return s
- if PY2 and isinstance(s, text_type):
- return s.encode(encoding, errors)
- elif PY3 and isinstance(s, binary_type):
- return s.decode(encoding, errors)
- elif not isinstance(s, (text_type, binary_type)):
- raise TypeError("not expecting type '%s'" % type(s))
- return s
-
-
-def ensure_text(s, encoding='utf-8', errors='strict'):
- """Coerce *s* to six.text_type.
-
- For Python 2:
- - `unicode` -> `unicode`
- - `str` -> `unicode`
-
- For Python 3:
- - `str` -> `str`
- - `bytes` -> decoded to `str`
- """
- if isinstance(s, binary_type):
- return s.decode(encoding, errors)
- elif isinstance(s, text_type):
- return s
- else:
- raise TypeError("not expecting type '%s'" % type(s))
-
-
-def python_2_unicode_compatible(klass):
- """
- A class decorator that defines __unicode__ and __str__ methods under Python 2.
- Under Python 3 it does nothing.
-
- To support Python 2 and 3 with a single code base, define a __str__ method
- returning text and apply this decorator to the class.
- """
- if PY2:
- if '__str__' not in klass.__dict__:
- raise ValueError("@python_2_unicode_compatible cannot be applied "
- "to %s because it doesn't define __str__()." %
- klass.__name__)
- klass.__unicode__ = klass.__str__
- klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
- return klass
-
-
-# Complete the moves implementation.
-# This code is at the end of this module to speed up module loading.
-# Turn this module into a package.
-__path__ = [] # required for PEP 302 and PEP 451
-__package__ = __name__ # see PEP 366 @ReservedAssignment
-if globals().get("__spec__") is not None:
- __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable
-# Remove other six meta path importers, since they cause problems. This can
-# happen if six is removed from sys.modules and then reloaded. (Setuptools does
-# this for some reason.)
-if sys.meta_path:
- for i, importer in enumerate(sys.meta_path):
- # Here's some real nastiness: Another "instance" of the six module might
- # be floating around. Therefore, we can't use isinstance() to check for
- # the six meta path importer, since the other six instance will have
- # inserted an importer with different class.
- if (type(importer).__name__ == "_SixMetaPathImporter" and
- importer.name == __name__):
- del sys.meta_path[i]
- break
- del i, importer
-# Finally, add the importer to the meta path import hook.
-sys.meta_path.append(_importer)
diff --git a/spyne/util/tdict.py b/spyne/util/tdict.py
index 82875e234..14a18428c 100644
--- a/spyne/util/tdict.py
+++ b/spyne/util/tdict.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -19,7 +18,6 @@
"""The typed dict module"""
-
from itertools import chain
@@ -84,7 +82,7 @@ def fromkeys(cls, S, v=None):
kt = vt = None
if len(S) > 0:
- kt, = set((type(s) for s in S))
+ (kt,) = set((type(s) for s in S))
if v is not None:
vt = type(v)
@@ -97,5 +95,8 @@ def fromkeys(cls, S, v=None):
return retval
def repr(self):
- return "tdict(kt=%s, vt=%s, data=%s)" % \
- (self._kt, self._vt, super(tdict, self).__repr__())
+ return "tdict(kt=%s, vt=%s, data=%s)" % (
+ self._kt,
+ self._vt,
+ super(tdict, self).__repr__(),
+ )
diff --git a/spyne/util/test.py b/spyne/util/test.py
index 48da40922..2ef5b780a 100644
--- a/spyne/util/test.py
+++ b/spyne/util/test.py
@@ -25,24 +25,26 @@
def _start_response(code, headers):
print(code, pformat(headers))
-def call_wsgi_app_kwargs(app, _mn='some_call', _headers=None, **kwargs):
+
+def call_wsgi_app_kwargs(app, _mn="some_call", _headers=None, **kwargs):
return call_wsgi_app(app, _mn, _headers, kwargs.items())
-def call_wsgi_app(app, mn='some_call', headers=None, body_pairs=None):
+
+def call_wsgi_app(app, mn="some_call", headers=None, body_pairs=None):
if headers is None:
headers = {}
if body_pairs is None:
body_pairs = []
- body_pairs = [(k,str(v)) for k,v in body_pairs]
+ body_pairs = [(k, str(v)) for k, v in body_pairs]
request = {
- 'QUERY_STRING': urlencode(body_pairs),
- 'PATH_INFO': '/%s' % mn,
- 'REQUEST_METHOD': 'GET',
- 'SERVER_NAME': 'spyne.test',
- 'SERVER_PORT': '0',
- 'wsgi.url_scheme': 'http',
+ "QUERY_STRING": urlencode(body_pairs),
+ "PATH_INFO": "/%s" % mn,
+ "REQUEST_METHOD": "GET",
+ "SERVER_NAME": "spyne.test",
+ "SERVER_PORT": "0",
+ "wsgi.url_scheme": "http",
}
print(headers)
@@ -55,14 +57,15 @@ def call_wsgi_app(app, mn='some_call', headers=None, body_pairs=None):
out_string.append(s)
if t == bytes:
- out_string = b''.join(out_string)
+ out_string = b"".join(out_string)
else:
- out_string = ''.join(out_string)
+ out_string = "".join(out_string)
return out_string
-from os import mkdir, getcwd
-from os.path import join, basename
+
+from os import getcwd, mkdir
+from os.path import basename, join
def show(elt, tn=None, stdout=True):
@@ -71,27 +74,28 @@ def show(elt, tn=None, stdout=True):
for frame in inspect.stack():
if frame[3].startswith("test_"):
- cn = frame[0].f_locals['self'].__class__.__name__
+ cn = frame[0].f_locals["self"].__class__.__name__
tn = "%s.%s" % (cn, frame[3])
break
else:
raise Exception("don't be lazy and pass test name.")
- from lxml import html, etree
+ from lxml import etree, html
+
out_string = etree.tostring(elt, pretty_print=True)
if stdout:
print(out_string)
- fn = '%s.html' % tn
- if basename(getcwd()) != 'test_html':
+ fn = "%s.html" % tn
+ if basename(getcwd()) != "test_html":
try:
- mkdir('test_html')
+ mkdir("test_html")
except OSError:
pass
- f = open(join("test_html", fn), 'wb')
+ f = open(join("test_html", fn), "wb")
else:
- f = open(fn, 'wb')
+ f = open(fn, "wb")
f.write(html.tostring(elt, pretty_print=True, doctype=""))
diff --git a/spyne/util/tlist.py b/spyne/util/tlist.py
index ee83666f7..e13b7c61b 100644
--- a/spyne/util/tlist.py
+++ b/spyne/util/tlist.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -59,7 +58,8 @@ def _type_check(self, val):
if not isinstance(val, self._types):
raise TypeError(
"Wrong type %s, this list can hold only instances of %s"
- % (type(val), str(self._types)))
+ % (type(val), str(self._types))
+ )
def __iadd__(self, other):
map(self._type_check, other)
diff --git a/spyne/util/toposort.py b/spyne/util/toposort.py
index 6fba0ce75..2b7c4ae99 100644
--- a/spyne/util/toposort.py
+++ b/spyne/util/toposort.py
@@ -37,18 +37,23 @@ def toposort2(data):
return
for k, v in data.items():
- v.discard(k) # Ignore self dependencies
+ v.discard(k) # Ignore self dependencies
# add items that are listed as dependencies but not as dependents to data
extra_items_in_deps = reduce(set.union, data.values()) - set(data.keys())
- data.update(dict([(item,set()) for item in extra_items_in_deps]))
+ data.update(dict([(item, set()) for item in extra_items_in_deps]))
while True:
- ordered = set(item for item,dep in data.items() if len(dep) == 0)
+ ordered = set(item for item, dep in data.items() if len(dep) == 0)
if len(ordered) == 0:
break
- yield sorted(ordered, key=lambda x:repr(x))
- data = dict([(item, (dep - ordered)) for item,dep in data.items()
- if item not in ordered])
+ yield sorted(ordered, key=lambda x: repr(x))
+ data = dict(
+ [
+ (item, (dep - ordered))
+ for item, dep in data.items()
+ if item not in ordered
+ ]
+ )
assert not data, "A cyclic dependency exists amongst\n%s" % pformat(data)
diff --git a/spyne/util/web.py b/spyne/util/web.py
index 936ca06d4..d91300c6a 100644
--- a/spyne/util/web.py
+++ b/spyne/util/web.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -26,34 +25,51 @@
from __future__ import absolute_import
import logging
+
logger = logging.getLogger(__name__)
from inspect import isclass
-from spyne import rpc, Any, AnyDict, NATIVE_MAP, M, Array, ComplexModelBase, \
- UnsignedInteger32, PushBase, Iterable, ModelBase, File, Service, \
- ResourceNotFoundError, Unicode
-
-from spyne.const import MAX_ARRAY_ELEMENT_NUM, MAX_DICT_ELEMENT_NUM, \
- MAX_STRING_FIELD_LENGTH, MAX_FIELD_NUM
+from spyne import (
+ NATIVE_MAP,
+ Any,
+ AnyDict,
+ Array,
+ ComplexModelBase,
+ File,
+ Iterable,
+ M,
+ ModelBase,
+ PushBase,
+ ResourceNotFoundError,
+ Service,
+ Unicode,
+ UnsignedInteger32,
+ rpc,
+)
+from spyne.const import (
+ MAX_ARRAY_ELEMENT_NUM,
+ MAX_DICT_ELEMENT_NUM,
+ MAX_FIELD_NUM,
+ MAX_STRING_FIELD_LENGTH,
+)
try:
- from spyne.store.relational.document import FileData
from sqlalchemy.orm.exc import DetachedInstanceError
+
+ from spyne.store.relational.document import FileData
except ImportError:
# these are used just for isinstance checks. so we just set it to an
# anonymous value
- FileData = type('__hidden', (object, ), {})
- DetachedInstanceError = type('__hidden', (Exception, ), {})
-
-from spyne.util import memoize, six
+ FileData = type("__hidden", (object,), {})
+ DetachedInstanceError = type("__hidden", (Exception,), {})
EXCEPTION_ADDRESS = None
try:
- from colorama.ansi import Fore
- from colorama.ansi import Style
+ from colorama.ansi import Fore, Style
+
RED = Fore.RED + Style.BRIGHT
GREEN = Fore.GREEN + Style.BRIGHT
RESET = Style.RESET_ALL
@@ -72,8 +88,9 @@ class WriterService(Service):
pass
-def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
- tags=None, prot=None):
+def log_repr(
+ obj, cls=None, given_len=None, parent=None, from_array=False, tags=None, prot=None
+):
"""Use this function if you want to serialize a ComplexModelBase instance to
logs. It will:
@@ -86,10 +103,10 @@ def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
tags = set()
if obj is None:
- return 'None'
+ return "None"
objcls = None
- if hasattr(obj, '__class__'):
+ if hasattr(obj, "__class__"):
objcls = obj.__class__
if objcls in (list, tuple):
@@ -107,7 +124,7 @@ def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
cls_attrs = None
logged = None
- if hasattr(cls, 'Attributes'):
+ if hasattr(cls, "Attributes"):
# init cls_attrs
if prot is None:
cls_attrs = cls.Attributes
@@ -119,11 +136,11 @@ def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
if not logged:
return "%s(...)" % cls.get_type_name()
- if logged == '...':
+ if logged == "...":
return "(...)"
- if logged == 'len':
- l = '?'
+ if logged == "len":
+ l = "?"
try:
if isinstance(obj, (list, tuple)):
l = str(sum([len(o) for o in obj]))
@@ -148,33 +165,33 @@ def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
retval = []
if isinstance(obj, dict):
- if logged == 'full':
+ if logged == "full":
for i, (k, v) in enumerate(obj.items()):
- retval.append('%r: %r' % (k, v))
+ retval.append("%r: %r" % (k, v))
- elif logged == 'keys':
+ elif logged == "keys":
for i, k in enumerate(obj.keys()):
if i >= MAX_DICT_ELEMENT_NUM:
retval.append("(...)")
break
- retval.append('%r: (...)' % (k,))
+ retval.append("%r: (...)" % (k,))
- elif logged == 'values':
+ elif logged == "values":
for i, v in enumerate(obj.values()):
if i >= MAX_DICT_ELEMENT_NUM:
retval.append("(...)")
break
- retval.append('(...): %s' % (log_repr(v, tags=tags),))
+ retval.append("(...): %s" % (log_repr(v, tags=tags),))
- elif logged == 'keys-full':
+ elif logged == "keys-full":
for k in obj.keys():
- retval.append('%r: (...)' % (k,))
+ retval.append("%r: (...)" % (k,))
- elif logged == 'values-full':
+ elif logged == "values-full":
for v in obj.values():
- retval.append('(...): %r' % (v,))
+ retval.append("(...): %r" % (v,))
elif logged is True: # default behaviour
for i, (k, v) in enumerate(obj.items()):
@@ -182,18 +199,17 @@ def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
retval.append("(...)")
break
- retval.append('%r: %s' % (k,
- log_repr(v, parent=k, tags=tags)))
+ retval.append("%r: %s" % (k, log_repr(v, parent=k, tags=tags)))
elif logged is None:
return "(...)"
else:
raise ValueError("Invalid value logged=%r", logged)
- return "{%s}" % ', '.join(retval)
+ return "{%s}" % ", ".join(retval)
else:
- if logged in ('full', 'keys-full', 'values-full'):
+ if logged in ("full", "keys-full", "values-full"):
retval = [repr(s) for s in obj]
else:
@@ -204,11 +220,11 @@ def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
retval.append(log_repr(v, tags=tags))
- return "[%s]" % ', '.join(retval)
+ return "[%s]" % ", ".join(retval)
- if ( issubclass(cls, Array)
- or (cls_attrs is not None and cls_attrs.max_occurs > 1) ) \
- and not from_array:
+ if (
+ issubclass(cls, Array) or (cls_attrs is not None and cls_attrs.max_occurs > 1)
+ ) and not from_array:
if id(obj) in tags:
return "%s(...)" % obj.__class__.__name__
@@ -219,22 +235,22 @@ def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
subcls = cls
if issubclass(cls, Array):
- subcls, = cls._type_info.values()
+ (subcls,) = cls._type_info.values()
if isinstance(obj, PushBase):
- return '[]'
+ return "[]"
if logged is None:
logged = cls_attrs.logged
for i, o in enumerate(obj):
- if logged != 'full' and i >= MAX_ARRAY_ELEMENT_NUM:
+ if logged != "full" and i >= MAX_ARRAY_ELEMENT_NUM:
retval.append("(...)")
break
retval.append(log_repr(o, subcls, from_array=True, tags=tags))
- return "[%s]" % (', '.join(retval))
+ return "[%s]" % (", ".join(retval))
if issubclass(cls, ComplexModelBase):
if id(obj) in tags:
@@ -253,7 +269,7 @@ def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
if not t.Attributes.logged:
continue
- if logged == '...':
+ if logged == "...":
retval.append("%s=(...)" % k)
continue
@@ -275,11 +291,11 @@ def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
retval.append("%s=%s" % (k, log_repr(v, t, parent=k, tags=tags)))
i += 1
- return "%s(%s)" % (cls.get_type_name(), ', '.join(retval))
+ return "%s(%s)" % (cls.get_type_name(), ", ".join(retval))
- if issubclass(cls, Unicode) and isinstance(obj, six.string_types):
+ if issubclass(cls, Unicode) and isinstance(obj, str):
if len(obj) > MAX_STRING_FIELD_LENGTH:
- return '%r(...)' % obj[:MAX_STRING_FIELD_LENGTH]
+ return "%r(...)" % obj[:MAX_STRING_FIELD_LENGTH]
return repr(obj)
@@ -299,39 +315,46 @@ def log_repr(obj, cls=None, given_len=None, parent=None, from_array=False,
def TReaderService(T, T_name):
class ReaderService(ReaderService):
- @rpc(M(UnsignedInteger32), _returns=T,
- _in_message_name='get_%s' % T_name,
- _in_variable_names={'obj_id': "%s_id" % T_name})
+ @rpc(
+ M(UnsignedInteger32),
+ _returns=T,
+ _in_message_name="get_%s" % T_name,
+ _in_variable_names={"obj_id": "%s_id" % T_name},
+ )
def get(ctx, obj_id):
return ctx.udc.session.query(T).filter_by(id=obj_id).one()
- @rpc(_returns=Iterable(T),
- _in_message_name='get_all_%s' % T_name)
+ @rpc(_returns=Iterable(T), _in_message_name="get_all_%s" % T_name)
def get_all(ctx):
return ctx.udc.session.query(T).order_by(T.id)
return ReaderService
-def TWriterService(T, T_name, put_not_found='raise'):
- assert put_not_found in ('raise', 'fix')
+def TWriterService(T, T_name, put_not_found="raise"):
+ assert put_not_found in ("raise", "fix")
+
+ if put_not_found == "raise":
- if put_not_found == 'raise':
def put_not_found(obj):
- raise ResourceNotFoundError('%s.id=%d' % (T_name, obj.id))
+ raise ResourceNotFoundError("%s.id=%d" % (T_name, obj.id))
+
+ elif put_not_found == "fix":
- elif put_not_found == 'fix':
def put_not_found(obj):
obj.id = None
class WriterService(WriterService):
- @rpc(M(T), _returns=UnsignedInteger32,
- _in_message_name='put_%s' % T_name,
- _in_variable_names={'obj': T_name})
+ @rpc(
+ M(T),
+ _returns=UnsignedInteger32,
+ _in_message_name="put_%s" % T_name,
+ _in_variable_names={"obj": T_name},
+ )
def put(ctx, obj):
if obj.id is None:
ctx.udc.session.add(obj)
- ctx.udc.session.flush() # so that we get the obj.id value
+ ctx.udc.session.flush() # so that we get the obj.id value
else:
if ctx.udc.session.query(T).get(obj.id) is None:
@@ -349,9 +372,11 @@ def put(ctx, obj):
return obj.id
- @rpc(M(UnsignedInteger32),
- _in_message_name='del_%s' % T_name,
- _in_variable_names={'obj_id': '%s_id' % T_name})
+ @rpc(
+ M(UnsignedInteger32),
+ _in_message_name="del_%s" % T_name,
+ _in_variable_names={"obj_id": "%s_id" % T_name},
+ )
def del_(ctx, obj_id):
count = ctx.udc.session.query(T).filter_by(id=obj_id).count()
if count == 0:
diff --git a/spyne/util/wsgi_wrapper.py b/spyne/util/wsgi_wrapper.py
index b15084935..974d02279 100644
--- a/spyne/util/wsgi_wrapper.py
+++ b/spyne/util/wsgi_wrapper.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -20,6 +19,7 @@
"""A Convenience module for wsgi wrapper routines."""
import logging
+
logger = logging.getLogger(__name__)
import os
@@ -54,16 +54,16 @@ def __init__(self, mounts=None):
assert callable(v), "%r is not a valid wsgi app." % v
app = v
- if k in ('', '/'):
+ if k in ("", "/"):
self.default = app
else:
self.mounts[k] = app
def __call__(self, environ, start_response):
- path_info = environ.get('PATH_INFO', '')
- fragments = [a for a in path_info.split('/') if len(a) > 0]
+ path_info = environ.get("PATH_INFO", "")
+ fragments = [a for a in path_info.split("/") if len(a) > 0]
- script = ''
+ script = ""
if len(fragments) > 0:
script = fragments[0]
@@ -71,22 +71,22 @@ def __call__(self, environ, start_response):
if app is self.default:
return app(environ, start_response)
- original_script_name = environ.get('SCRIPT_NAME', '')
+ original_script_name = environ.get("SCRIPT_NAME", "")
if len(script) > 0:
script = "/" + script
- environ['SCRIPT_NAME'] = ''.join(('/', original_script_name, script))
- pi = ''.join(('/', '/'.join(fragments[1:])))
+ environ["SCRIPT_NAME"] = "".join(("/", original_script_name, script))
+ pi = "".join(("/", "/".join(fragments[1:])))
- if pi == '/':
- environ['PATH_INFO'] = ''
+ if pi == "/":
+ environ["PATH_INFO"] = ""
else:
- environ['PATH_INFO'] = pi
+ environ["PATH_INFO"] = pi
return app(environ, start_response)
-def run_twisted(apps, port, static_dir='.', interface='0.0.0.0'):
+def run_twisted(apps, port, static_dir=".", interface="0.0.0.0"):
"""Twisted wrapper for the spyne.server.wsgi.WsgiApplication. Twisted can
use one thread per request to run services, so code wrapped this way does
not necessarily have to respect twisted way of doing things.
@@ -102,10 +102,9 @@ def run_twisted(apps, port, static_dir='.', interface='0.0.0.0'):
import twisted.web.server
import twisted.web.static
-
+ from twisted.internet import reactor
from twisted.web.resource import Resource
from twisted.web.wsgi import WSGIResource
- from twisted.internet import reactor
if static_dir != None:
static_dir = os.path.abspath(static_dir)
diff --git a/spyne/util/xml.py b/spyne/util/xml.py
index d52ada5f4..5cb490e08 100644
--- a/spyne/util/xml.py
+++ b/spyne/util/xml.py
@@ -1,4 +1,3 @@
-
#
# spyne - Copyright (C) Spyne contributors.
#
@@ -21,24 +20,22 @@
"""The `spyne.util.xml` module contains various Xml and Xml Schema related
utility functions.
"""
+
from inspect import isgenerator
+from io import BytesIO
+from os.path import abspath, dirname
from lxml import etree
-from os.path import dirname
-from os.path import abspath
-
-from spyne import ServiceBase, Application, srpc
+from spyne import Application, ServiceBase, srpc
from spyne.context import FakeContext
from spyne.interface import Interface
from spyne.interface.xml_schema import XmlSchema
-from spyne.interface.xml_schema.parser import XmlSchemaParser, Thier_repr, PARSER
+from spyne.interface.xml_schema.parser import PARSER, Thier_repr, XmlSchemaParser
from spyne.protocol import ProtocolMixin
from spyne.protocol.cloth import XmlCloth
-
from spyne.protocol.xml import XmlDocument
from spyne.util.appreg import unregister_application
-from spyne.util.six import BytesIO
from spyne.util.tlist import tlist
@@ -99,7 +96,7 @@ def get_validation_schema(models, default_namespace=None):
def _dig(par):
for elt in par:
- elt.tag = elt.tag.split('}')[-1]
+ elt.tag = elt.tag.split("}")[-1]
_dig(elt)
@@ -121,8 +118,7 @@ def get_object_as_xml(inst, cls=None, root_tag_name=None, no_namespace=False):
cls = inst.__class__
parent = etree.Element("parent")
- _xml_object.to_parent(None, cls, inst, parent, cls.get_namespace(),
- root_tag_name)
+ _xml_object.to_parent(None, cls, inst, parent, cls.get_namespace(), root_tag_name)
if no_namespace:
_dig(parent)
etree.cleanup_namespaces(parent)
@@ -130,8 +126,9 @@ def get_object_as_xml(inst, cls=None, root_tag_name=None, no_namespace=False):
return parent[0]
-def get_object_as_xml_polymorphic(inst, cls=None, root_tag_name=None,
- no_namespace=False):
+def get_object_as_xml_polymorphic(
+ inst, cls=None, root_tag_name=None, no_namespace=False
+):
"""Returns an ElementTree representation of a
:class:`spyne.model.complex.ComplexModel` subclass.
@@ -146,29 +143,32 @@ def get_object_as_xml_polymorphic(inst, cls=None, root_tag_name=None,
cls = inst.__class__
if no_namespace:
- app = Application([ServiceBase], tns="",
- out_protocol=XmlDocument(polymorphic=True))
+ app = Application(
+ [ServiceBase], tns="", out_protocol=XmlDocument(polymorphic=True)
+ )
else:
tns = cls.get_namespace()
if tns is None:
raise ValueError(
- "Either set a namespace for %r or pass no_namespace=True"
- % (cls, ))
+ "Either set a namespace for %r or pass no_namespace=True" % (cls,)
+ )
class _DummyService(ServiceBase):
@srpc(cls)
def f(_):
pass
- app = Application([_DummyService], tns=tns,
- out_protocol=XmlDocument(polymorphic=True))
+ app = Application(
+ [_DummyService], tns=tns, out_protocol=XmlDocument(polymorphic=True)
+ )
unregister_application(app)
parent = etree.Element("parent", nsmap=app.interface.nsmap)
- app.out_protocol.to_parent(None, cls, inst, parent, cls.get_namespace(),
- root_tag_name)
+ app.out_protocol.to_parent(
+ None, cls, inst, parent, cls.get_namespace(), root_tag_name
+ )
if no_namespace:
_dig(parent)
@@ -188,22 +188,23 @@ def get_xml_as_object_polymorphic(elt, cls):
tns = cls.get_namespace()
if tns is None:
- raise ValueError("Please set a namespace for %r" % (cls, ))
+ raise ValueError("Please set a namespace for %r" % (cls,))
class _DummyService(ServiceBase):
@srpc(cls)
def f(_):
pass
- app = Application([_DummyService], tns=tns,
- in_protocol=XmlDocument(polymorphic=True))
+ app = Application(
+ [_DummyService], tns=tns, in_protocol=XmlDocument(polymorphic=True)
+ )
unregister_application(app)
return app.in_protocol.from_element(FakeContext(app=app), cls, elt)
-def get_object_as_xml_cloth(inst, cls=None, no_namespace=False, encoding='utf8'):
+def get_object_as_xml_cloth(inst, cls=None, no_namespace=False, encoding="utf8"):
"""Returns an ElementTree representation of a
:class:`spyne.model.complex.ComplexModel` subclass.
@@ -247,8 +248,9 @@ def get_xml_as_object(elt, cls):
return _xml_object.from_element(None, cls, elt)
-def parse_schema_string(s, files={}, repr_=Thier_repr(with_ns=False),
- skip_errors=False):
+def parse_schema_string(
+ s, files={}, repr_=Thier_repr(with_ns=False), skip_errors=False
+):
"""Parses a schema string and returns a _Schema object.
:param s: The string or bytes object that contains the schema document.
@@ -262,12 +264,14 @@ def parse_schema_string(s, files={}, repr_=Thier_repr(with_ns=False),
"""
elt = etree.fromstring(s, parser=PARSER)
- return XmlSchemaParser(files, repr_=repr_,
- skip_errors=skip_errors).parse_schema(elt)
+ return XmlSchemaParser(files, repr_=repr_, skip_errors=skip_errors).parse_schema(
+ elt
+ )
-def parse_schema_element(elt, files={}, repr_=Thier_repr(with_ns=False),
- skip_errors=False):
+def parse_schema_element(
+ elt, files={}, repr_=Thier_repr(with_ns=False), skip_errors=False
+):
"""Parses a `` element and returns a _Schema object.
:param elt: The `` element, an lxml.etree._Element instance.
@@ -280,12 +284,14 @@ def parse_schema_element(elt, files={}, repr_=Thier_repr(with_ns=False),
:return: :class:`spyne.interface.xml_schema.parser._Schema` instance.
"""
- return XmlSchemaParser(files, repr_=repr_,
- skip_errors=skip_errors).parse_schema(elt)
+ return XmlSchemaParser(files, repr_=repr_, skip_errors=skip_errors).parse_schema(
+ elt
+ )
-def parse_schema_file(file_name, files=None, repr_=Thier_repr(with_ns=False),
- skip_errors=False):
+def parse_schema_file(
+ file_name, files=None, repr_=Thier_repr(with_ns=False), skip_errors=False
+):
"""Parses a schema file and returns a _Schema object. Schema files typically
have the `*.xsd` extension.
@@ -303,7 +309,8 @@ def parse_schema_file(file_name, files=None, repr_=Thier_repr(with_ns=False),
if files is None:
files = dict()
- elt = etree.fromstring(open(file_name, 'rb').read(), parser=PARSER)
+ elt = etree.fromstring(open(file_name, "rb").read(), parser=PARSER)
wd = abspath(dirname(file_name))
- return XmlSchemaParser(files, wd, repr_=repr_,
- skip_errors=skip_errors).parse_schema(elt)
+ return XmlSchemaParser(
+ files, wd, repr_=repr_, skip_errors=skip_errors
+ ).parse_schema(elt)