Remove pre-8.3 XML namespace fallback - #1863
Draft
jacalata wants to merge 2 commits into
Draft
Conversation
The `Namespace` class detected `http://tableausoftware.com/api` (the pre-8.3 namespace) at runtime on every XML response and let the parser silently switch namespaces if it saw the old one. That behavior has been unreachable for years: the library's `minimum_supported_server_version` is 2.3, which corresponds to Tableau Server 10.0 -- shipped in 2016, three years after the namespace changed. Every server TSC has ever admitted uses `http://tableau.com/api`. Removes: - `tableauserverclient/namespace.py` (the module) and everything it exported: `Namespace`, `UnknownNamespaceError`, `OLD_NAMESPACE`, `NEW_NAMESPACE`, `NAMESPACE_RE`. - `Server._namespace` instance and the per-response `.detect(...)` call in `Endpoint._make_request` and both sign-in paths in `Auth`. Keeps: - The public `TSC.DEFAULT_NAMESPACE` re-export -- now sourced from `tableauserverclient.server.server.NAMESPACE`, which is the canonical constant. Same string value. - `Server.namespace` property -- still returns the `{"t": NAMESPACE}` dict callers pass to ElementTree's `namespaces=` kwarg. Same shape. Callers who imported directly from `tableauserverclient.namespace` (rather than `TSC.DEFAULT_NAMESPACE`) will break; the CHANGELOG entry calls this out. Fixes #1046. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR removes runtime XML namespace detection that allowed parsing legacy (pre-Tableau Server 8.3) REST API XML responses, standardizing the client on the modern http://tableau.com/api namespace in line with the library’s long-standing minimum supported server/API versions.
Changes:
- Removed the
tableauserverclient.namespacemodule and eliminated per-response namespace detection calls. - Centralized the namespace constant in
server.serverand updatedTSC.DEFAULT_NAMESPACEto keep the public re-export working. - Updated server/endpoint code paths to always use the fixed namespace map.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tableauserverclient/server/server.py | Removes per-instance namespace detector and introduces fixed namespace constants/map. |
| tableauserverclient/server/endpoint/endpoint.py | Removes the XML-response namespace detection hook in _make_request. |
| tableauserverclient/server/endpoint/auth_endpoint.py | Removes namespace detection during sign-in and site switching flows. |
| tableauserverclient/namespace.py | Deletes the legacy namespace detection module and exported symbols. |
| tableauserverclient/init.py | Updates DEFAULT_NAMESPACE re-export to come from the new namespace source. |
| CHANGELOG.md | Documents the breaking removal of legacy namespace fallback and module exports. |
Suppressed comments (2)
tableauserverclient/server/endpoint/auth_endpoint.py:159
- With namespace auto-detection removed, a legacy-namespace (or otherwise unexpected) XML response can make
find(...).get(...)raiseAttributeError. Adding an explicit check and raisingServerResponseErrorproduces a clearer, user-facing failure mode for unsupported namespaces/servers.
parsed_response = fromstring(server_response.content)
site_id = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("id", None)
site_url = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("contentUrl", None)
tableauserverclient/server/endpoint/auth_endpoint.py:86
- With namespace auto-detection removed, a legacy-namespace (or otherwise unexpected) XML response will make
find(...).get(...)raise anAttributeError, which is hard to diagnose. It’s better to explicitly check that the expected elements are present and raiseServerResponseErrorwith a message that points to a likely namespace / server-version mismatch.
This issue also appears on line 157 of the same file.
parsed_response = fromstring(server_response.content)
site_id = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("id", None)
site_url = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("contentUrl", None)
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+295
to
+296
| def namespace(self): | ||
| return self._namespace() | ||
| return _NAMESPACE_MAP |
| @@ -1,5 +1,5 @@ | |||
| from tableauserverclient.bin._version import get_versions | |||
| from tableauserverclient.namespace import NEW_NAMESPACE as DEFAULT_NAMESPACE | |||
| from tableauserverclient.server.server import NAMESPACE as DEFAULT_NAMESPACE | |||
…hared state Copilot flagged that Server.namespace returned the module-level _NAMESPACE_MAP directly, so a caller mutating the returned dict would have polluted every other Server instance in the process. Old namespace- handling code returned a per-instance dict, so no cross-instance pollution was possible. Wrap in dict(...) to restore that behavior.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft -- opening for discussion. Happy to add a deprecation cycle instead of an outright removal if that's preferred.
Summary
Removes the runtime XML namespace detection that let TSC accept responses from Tableau Server versions predating 8.3 (2013,
http://tableausoftware.com/api). The library'sminimum_supported_server_versionhas been 2.3 for years (Tableau Server 10.0, 2016), so the detection has been unreachable for a decade.Fixes #1046.
What changes
Removed:
tableauserverclient/namespace.py(the whole module) and the symbols it exported:Namespace,UnknownNamespaceError,OLD_NAMESPACE,NEW_NAMESPACE,NAMESPACE_RE.Server._namespaceand the per-response.detect(...)call inEndpoint._make_requestand both sign-in paths inAuth.Kept:
TSC.DEFAULT_NAMESPACEre-export -- now sourced fromtableauserverclient.server.server.NAMESPACE. Same string value.Server.namespaceproperty -- still returns the{"t": NAMESPACE}dict callers pass to ElementTree'snamespaces=kwarg. Same shape.Compatibility
Callers who imported directly from
tableauserverclient.namespace(rather than the documentedTSC.DEFAULT_NAMESPACE) will break. The CHANGELOG entry calls this out. Given the module was internal in every sense except being top-level, I opted for outright removal, but a deprecation shim (namespace.pybecomes a warning-emitting alias, removed one minor release later) is easy to add if that's the house style.Why now
Discussion in #1039 (2022) already noted the fallback was safe to drop; the issue has been open since. Nothing in the diff is complicated -- the code is simply dead.
Test plan
from tableauserverclient.namespace,UnknownNamespaceError,_namespace.detect,OLD_NAMESPACE,NEW_NAMESPACE,namespace.Namespaceinside the repo -- only remaining reference is the CHANGELOG entry.mypyandblackclean via pre-commit.🤖 Generated with Claude Code