Skip to content

DOC: document None return for late-binding transformers - #1637

Open
shaikn6 wants to merge 3 commits into
pyproj4:mainfrom
shaikn6:docs/transformer-late-binding-none
Open

shaikn6 wants to merge 3 commits into
pyproj4:mainfrom
shaikn6:docs/transformer-late-binding-none

Conversation

@shaikn6

@shaikn6 shaikn6 commented Sep 14, 2026

Copy link
Copy Markdown

What

Document why Transformer.to_wkt(), to_json(), and to_json_dict() can return None / raise TypeError.

Why / evidence

Transformer.from_crs() without an area_of_interest builds a "late-binding" transformer that may represent several candidate coordinate operations rather than one, so there is no single WKT/JSON string to return. The docstrings promised a str/dict unconditionally, which surprised users (#1549) -- to_json() returns None, and to_json_dict() then raises TypeError: the JSON object must be str, bytes or bytearray, not NoneType because it feeds that None into json.loads. Maintainers phaarnes/rouault confirmed this is expected PROJ behavior and snowman2 agreed it should be documented, but no doc PR followed.

Change

Added a Notes section to each of the three methods' docstrings in pyproj/transformer.py explaining the late-binding cause and the fix (pass area_of_interest, or use Transformer.from_pipeline(), to get a transformer for a single concrete operation).

Verified

Reproduced with pyproj 3.8.0 in a clean venv:

from pyproj import Transformer
t = Transformer.from_crs("EPSG:4258", "EPSG:32633")
t.to_json()       # None
t.to_wkt()        # None
t.to_json_dict()  # TypeError: the JSON object must be str, bytes or bytearray, not NoneType

Confirmed the documented workaround resolves it:

from pyproj.transformer import AreaOfInterest
t = Transformer.from_crs("EPSG:4258", "EPSG:32633",
        area_of_interest=AreaOfInterest(5, 58, 15, 62))
t.to_json()  # returns a real PROJJSON string
t.to_wkt()   # returns a real WKT string

python3 -c "import ast; ast.parse(open('pyproj/transformer.py').read())" -- syntax OK. Docs-only change, no code path modified.

Fixes #1549

Transformer.to_wkt()/to_json()/to_json_dict() silently return None (or
raise TypeError from to_json_dict) when the transformer was built via
from_crs() without an area_of_interest, because it represents multiple
candidate operations rather than a single one with a defined string
representation. Confirmed by maintainers in pyproj4#1549 as expected but
undocumented behavior. Document the cause and the area_of_interest /
from_pipeline() workaround on all three methods.

Fixes pyproj4#1549
Comment thread pyproj/transformer.py
@shaikn6 shaikn6 closed this Sep 19, 2026
@shaikn6 shaikn6 reopened this Sep 19, 2026
@codecov

codecov Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.84%. Comparing base (e81e5e5) to head (2c8e924).
⚠️ Report is 54 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1637      +/-   ##
==========================================
- Coverage   95.85%   95.84%   -0.01%     
==========================================
  Files          20       20              
  Lines        1880     1879       -1     
==========================================
- Hits         1802     1801       -1     
  Misses         78       78              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@snowman2 snowman2 added the documentation Docs need updating label Sep 23, 2026
@snowman2 snowman2 added this to the 3.8.1 milestone Sep 23, 2026
@snowman2

Copy link
Copy Markdown
Member

@shaikn6 mind updating the function type hint for the return from str to str | None?

@shaikn6

shaikn6 commented Sep 23, 2026

Copy link
Copy Markdown
Author

Done — to_wkt and to_json now annotate str | None, and I updated their docstring Returns types to match. Left to_json_dict as dict since it raises TypeError rather than returning None; happy to change that too if you'd rather it be explicit.

(The one failing Conda macOS job looks like CI infra noise — this branch is docs/annotations only and an earlier run on the same commit range passed.)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Docs need updating

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Transformer.to_json() returns None for valid CRS pair

2 participants