@@ -400,6 +400,100 @@ Examples of PyAnsys projects that have these optional dependencies are:
400400- `PyAnsys Geometry targets <https://github.com/ansys/pyansys-geometry/blob/e6d8210f9d79718d607a2f4b2e8ead33babcbfca/pyproject.toml#L44-L58 >`_
401401- `PyACP targets <https://github.com/ansys/pyacp/blob/f4d8c1779cd451b1fc8ef649cc3b2cd5799ff11a/pyproject.toml#L89-L110 >`_
402402
403+ Dependency version range
404+ ------------------------
405+
406+ .. note ::
407+
408+ This guidance applies only to PyAnsys *library * projects. For projects
409+ which deliver an *application * or *dedicated workflow *, it is
410+ recommended to fully pinning all (direct and transitive) dependencies.
411+
412+ When specifying dependencies in a project, it is generally recommended to avoid
413+ setting upper version limits unless it is absolutely necessary. The reason for
414+ that is because arbitrarily restricting a dependency to be lower than a
415+ certain version (for example `numpy<2.0 `) can prevent your project from working
416+ with newer and perfectly compatible versions, and often causes more problems
417+ than it solves. Such restrictions limit forward compatibility, block users from
418+ upgrading dependencies, and increase the risk of version conflicts.
419+
420+ This issue is even more critical in the context of the PyAnsys `metapackage `_
421+ which install many PyAnsys projects. In this setup, having strict upper bounds
422+ on versions can easily result in unsatisfiable dependency constraints across
423+ the ecosystem. For instance, if a package declares a dependency on `numpy<2.0 `
424+ despite being compatible with later versions, and another package requires
425+ `numpy>=2.0.0 ` to leverage a new feature, it becomes impossible to install
426+ both packages simultaneously. This occurs even though no actual incompatibility
427+ exists between them, and it can lead to frustration for users and maintainers
428+ as it prevents otherwise compatible packages from being used together seamlessly.
429+
430+ It is better to define only a minimum version (`>= `) and rely on Continuous
431+ Integration (CI) to detect real breakages as dependencies evolve. If a future
432+ version does introduce a breaking change, you can then add an upper bound with
433+ a clear explanation. For example:
434+
435+ .. code-block :: toml
436+
437+ [project]
438+ dependencies = [
439+ "numpy<2.0", # breaking changes in Python and C APIs'.
440+ ]
441+
442+ Setting a lower bound (`>= `) is considered good practice for multiple reasons.
443+ First, it documents the oldest version of a dependency that your project
444+ explicitly supports. It is often the oldest version that is compatible with
445+ the Python versions you support. For example, if your project supports
446+ Python versions from `3.11 ` to `3.13 `, you need to ensure that all dependencies
447+ are compatible with at least Python `3.11 `. This is important for users who may
448+ be using older versions of Python and want to ensure compatibility with your
449+ project. In other cases, the lower bound is related to the version where
450+ certain key features your code relies on were first introduced. For instance,
451+ if your code uses an API or behavior that only appeared in version `1.3 `,
452+ setting `>=1.3 ` communicates both a technical requirement and an implicit
453+ contract to your users and contributors.
454+
455+ This helps avoiding unexpected breakages when someone installs your project
456+ in an environment with older versions of dependencies. Rather than encountering
457+ obscure runtime errors or missing features, the version constraint prevents
458+ your project to be installed. It also helps to maintain clarity for long-term
459+ maintenance and simplifies debugging.
460+
461+ Below is an example of a dependency specification that follows these guidelines:
462+
463+ .. tab-set ::
464+
465+ .. tab-item :: flit
466+
467+ .. code-block :: toml
468+
469+ [project]
470+ dependencies = [
471+ "matplotlib>=3.5.2",
472+ "numpy>=1.20.0",
473+ ]
474+
475+ .. tab-item :: poetry
476+
477+ .. code-block :: toml
478+
479+ [tool.poetry.dependencies]
480+ matplotlib = ">=3.5.2"
481+ numpy = ">=1.20.0"
482+
483+ .. tab-item :: setuptools
484+
485+ .. code-block :: python
486+
487+ from setuptools import setup
488+
489+ setup(
490+ ... ,
491+ install_requires = [
492+ " matplotlib >= 3.5.2" ,
493+ " numpy >= 1.20.0" ,
494+ ],
495+ )
496+
403497 Dependabot
404498----------
405499
0 commit comments