Skip to content
Merged
8 changes: 8 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ jobs:
with:
submodules: recursive
persist-credentials: false
- name: Install system libraries for lxml
run: |
sudo apt-get update
sudo apt-get install -y libxml2-dev libxslt1-dev
- name: Use Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
Expand Down Expand Up @@ -78,6 +82,10 @@ jobs:
with:
submodules: recursive
persist-credentials: false
- name: Install system libraries for lxml
run: |
sudo apt-get update
sudo apt-get install -y libxml2-dev libxslt1-dev
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405
with:
Expand Down
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Read [CONTRIBUTING.rst](CONTRIBUTING.rst) for code style, linting (e.g. `make li

## Testing

- Prefer **function-based** pytest tests (module-level `def test_...`) over class-based tests (`class Test...`).
- When adding tests to a file that already uses class-based pytest structure (e.g. `tests/test_jsonld.py`), add them as methods on the appropriate existing class — do not introduce a parallel standalone function-based test. A repo-wide refactor to function-based tests is planned but not yet landed; until then, match each file's existing structure.
- For brand-new test files, prefer function-based pytest tests (module-level `def test_...`) over class-based tests.
- Use descriptive test names that reflect behavior (e.g. `test_remote_context_via_link_alternate`).

## Committing
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See [AGENTS.md](AGENTS.md) for project-specific agent guidance.
4 changes: 2 additions & 2 deletions lib/pyld/jsonld.py
Original file line number Diff line number Diff line change
Expand Up @@ -5842,8 +5842,8 @@ def _expand_iri(

# resolve against base
rval = value
# if there is a base in the active context, use that
if '@base' in active_ctx:
# if a base was passed and the active context has a base, use that
if base is not None and '@base' in active_ctx:
Comment thread
anatoly-scherbakov marked this conversation as resolved.
# the None case preserves rval as potentially relative
if active_ctx['@base'] is not None:
resolved_base = (
Expand Down
30 changes: 30 additions & 0 deletions tests/test_jsonld.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,36 @@ def test_missing_base(self):
got = jsonld.expand(input)
assert got == expected

def test_base_does_not_expand_property_terms(self):
"""
Regression test: @base must not be used to expand property keys.

Property names are expanded vocabulary-relative: @vocab, term
definitions, compact IRIs with a defined prefix, etc. The active
context's @base is for document-relative IRI resolution where the
algorithms pass that flag (e.g. certain @id and @type values), not
for turning arbitrary keys into absolute IRIs. Here the context sets
only @base; `name` has no term definition and no @vocab, so it
cannot become an absolute property IRI and must be dropped.

See: https://www.w3.org/TR/json-ld11-api/#iri-expansion
"""
doc = {
'@context': {'@base': 'https://schema.org/'},
'@id': 'https://w3.org/yaml-ld/',
'@type': 'WebContent',
'name': 'YAML-LD',
}
result = jsonld.expand(doc)
# `name` has no vocabulary-relative mapping (@vocab or term
# definition); @base must not supply one. The key is dropped.
assert result == [
{
'@id': 'https://w3.org/yaml-ld/',
'@type': ['https://schema.org/WebContent'],
}
]


class TestFrame:
# Issue 11 - PR: https://github.com/digitalbazaar/pyld/issues/149
Expand Down
Loading