{"id":5382,"library":"purl","title":"purl","description":"purl is an immutable URL class designed for easy URL-building and manipulation in Python. It provides a clean API for interrogation and transformation of URLs, aiming to offer a more intuitive experience than the standard library's urlparse and urllib modules. The current version is 1.6, released in May 2021, and the project is actively maintained.","status":"active","version":"1.6","language":"en","source_language":"en","source_url":"https://github.com/codeinthehole/purl","tags":["url","parsing","manipulation","immutable","url-builder"],"install":[{"cmd":"pip install purl","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"URL","correct":"from purl import URL"},{"symbol":"Template","correct":"from purl import Template"}],"quickstart":{"code":"from purl import URL\n\n# Constructing a URL\nu = URL('https://www.example.com/path/to/resource?id=123&lang=en#section-1')\nprint(f\"Original URL: {u}\")\n\n# Accessing parts of the URL\nprint(f\"Scheme: {u.scheme()}\")\nprint(f\"Host: {u.host()}\")\nprint(f\"Path: {u.path()}\")\nprint(f\"Query parameter 'id': {u.query_param('id')}\")\n\n# Modifying the URL (returns a *new* URL object)\nnew_u = u.query_param('lang', 'fr').remove_query_param('id').fragment('top')\nprint(f\"Modified URL: {new_u}\")\nprint(f\"Original URL (unchanged): {u}\")\n\n# Chaining operations\nchained_url = URL('http://api.example.com').path('v1').path_segment(1, 'users').query_param('sort', 'asc')\nprint(f\"Chained URL: {chained_url}\")","lang":"python","description":"Demonstrates how to construct a URL object, access its various components, and perform modifications. Note that all modification methods return a new URL instance due to the library's immutable design."},"warnings":[{"fix":"Always capture the return value of modification methods, e.g., `new_url = old_url.path('new_path')`.","message":"URL objects are immutable. Any method that appears to 'modify' the URL (e.g., `path()`, `query_param()`, `add_query_param()`) will return a *new* `URL` instance with the changes, leaving the original object untouched. Users must assign the result of these operations to a new variable or reassign the original variable.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be mindful that `u.some_method()` retrieves a value, while `u.some_method(new_value)` returns a new URL object with `new_value` applied. Always check if you are getting a value or a new instance.","message":"Accessor methods (e.g., `u.path()`) are overloaded to also act as mutator methods (e.g., `u.path('new/path')`). When used as a mutator, they will return a *new* `URL` instance, consistent with the immutability principle. This can be confusing if not explicitly understood, as it does not modify the object in place.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Verify that you are installing and importing the correct library (`pip install purl` for this library) based on your intended use case.","message":"The `purl` library (for general URL manipulation) should not be confused with `packageurl-python` (for Package URLs, or PURLs, specification). They are distinct libraries with different purposes, despite the similar naming. Ensure you import `from purl import URL` for this library.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}