diff --git a/README.md b/README.md index 1092dca627..b1cca01d37 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,13 @@ estimating asset prices: - **Panel models**: - Fixed effects (maximum two-way) + - Random effects - First difference regression - Between estimator for panel data - Pooled regression for panel data - Fama-MacBeth estimation of panel models + - Specification tests: the Hausman test of random effects against + fixed effects and the Pesaran CD test of cross-sectional dependence - **High-dimensional Regression**: - Absorbing Least Squares @@ -28,6 +31,9 @@ estimating asset prices: - Limited Information Maximum Likelihood - k-class Estimators - Generalized Method of Moments, also with continuously updating + - Jackknife IV (JIVE) + - Specification tests: the Cragg-Donald and Kleibergen-Paap rank tests + of the first stage (underidentification) - **Factor Asset Pricing Models**: - 2- and 3-step estimation @@ -89,7 +95,7 @@ mod = IV2SLS.from_formula('np.log(wage) ~ 1 + exper + exper ** 2 + [educ ~ mothe The expressions in the `[ ]` indicate endogenous regressors (before `~`) and the instruments. -## Installing +## Installation The latest release can be installed using pip @@ -97,7 +103,13 @@ The latest release can be installed using pip pip install linearmodels ``` -The main branch can be installed by cloning the repo and running setup +Binary wheels are available for Windows, macOS and Linux. Without a wheel, pip +builds linearmodels from source, which requires a C compiler. + +The main branch can be installed by cloning the repo and building it with pip. +The build uses [meson-python](https://mesonbuild.com/meson-python/), and pip +installs the other build requirements (Cython, NumPy and setuptools_scm) +automatically. ```bash git clone https://github.com/bashtage/linearmodels @@ -105,19 +117,24 @@ cd linearmodels pip install . ``` +To work on linearmodels, install the requirements and then build an editable +install + +```bash +python -m pip install -r requirements.txt -r requirements-dev.txt +python -m pip install -e . --no-build-isolation +``` + ## Documentation [Stable Documentation](https://bashtage.github.io/linearmodels/) is -built on every tagged version using -[doctr](https://github.com/drdoctr/doctr). +built by [GitHub Actions](https://github.com/bashtage/linearmodels/blob/main/.github/workflows/generate-documentation.yml) +when a release is published. [Development Documentation](https://bashtage.github.io/linearmodels/devel) -is automatically built on every successful build of main. +is built by the same workflow on every push to main. ## Plan and status -Should eventually add some useful linear model estimators such as panel -regression. Currently only the single variable IV estimators are polished. - - Linear Instrumental variable estimation - **complete** - Linear Panel model estimation - **complete** - Fama-MacBeth regression - **complete** @@ -128,21 +145,34 @@ regression. Currently only the single variable IV estimators are polished. ## Requirements +**linearmodels 7.1 is the last release that supports Python 3.10 and NumPy 1.x +(NumPy < 2).** Later releases will raise the minimum supported versions of +Python, NumPy and the other dependencies. + ### Running - Python 3.10+ -- NumPy (1.22+) +- NumPy (1.22.3+) - SciPy (1.8+) - pandas (1.4+) - statsmodels (0.13.1+) -- formulaic (1.0.0+) +- formulaic (1.2.1+) +- pyhdfe (0.1+) +- mypy_extensions (0.4+) +- packaging - xarray (0.16+, optional) -- Cython (3.0.10+, optional) +### Building from source + +- A C compiler +- Cython (3.1.0+) +- meson-python +- NumPy (2.0+) +- setuptools_scm (9.2+) ### Testing -- py.test +- pytest (9.0+) ### Documentation diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..f436157150 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,44 @@ +# Security Policy + +## Supported versions + +Only the latest release of linearmodels is supported. This is currently the +7.1.x series. Security fixes are not backported to earlier releases, so please +upgrade before reporting a problem that you found in an older release. + +## Reporting a vulnerability + +Please report suspected security vulnerabilities **privately**. Do not report +them in a public issue, pull request or discussion, since that tells everyone +about the problem before a fix is available. + +The preferred way to report a vulnerability is GitHub private vulnerability +reporting: + + + +If you cannot use GitHub, email the maintainer, Kevin Sheppard, at +, which is the address listed in `pyproject.toml`. +Use a subject line that makes clear that this is a security report, for example +"linearmodels security vulnerability". + +## What to include + +A report is easiest to act on if it contains: + +- A description of the vulnerability and its impact: what an attacker can do, + and what they need in order to do it. +- The affected function, class or module, and the version of linearmodels where + you found the problem. +- Steps to reproduce the problem, ideally as a short, self-contained script. +- The versions of Python, NumPy, SciPy, pandas and statsmodels, and your + operating system. +- A suggested fix or mitigation, if you have one. +- Whether the problem has been disclosed elsewhere, any disclosure deadline that + you plan to follow, and whether and how you would like to be credited. + +## What to expect + +linearmodels is a volunteer project, so responses are best effort. There is no +guaranteed response time or fix date. For a confirmed vulnerability, the +maintainer will work with you on a fix and on the timing of its disclosure. diff --git a/meson.build b/meson.build index e671988bd8..ead2e46b2e 100644 --- a/meson.build +++ b/meson.build @@ -11,8 +11,8 @@ cc = meson.get_compiler('c') cy = meson.get_compiler('cython') cython = find_program(cy.cmd_array()[0]) -if not cy.version().version_compare('>=3.0.10') - error('linearmodels requires Cython >= 3.0.10') +if not cy.version().version_compare('>=3.1.0') + error('linearmodels requires Cython >= 3.1.0') endif py = import('python').find_installation(pure: false) diff --git a/pyproject.toml b/pyproject.toml index f7b95e7f42..fbab4e4a4d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,22 +2,23 @@ build-backend = 'mesonpy' requires = [ 'meson-python', - "cython>=3.0.13,<4", # Sync with CYTHON_MIN_VER in setup + "cython>=3.1.0,<4", # Sync with the Cython check in meson.build "numpy>=2.0.0,<3", "setuptools_scm>=9.2.0,<10", ] [project] name = "linearmodels" -# Keep syned with requirements.txt +# Keep in sync with requirements.txt dependencies = [ "numpy>=1.22.3,<3", "pandas>=1.4.0", "scipy>=1.8.0", - "statsmodels>=0.13.0", + "statsmodels>=0.13.1", # The first release with a wheel for Python 3.10 "mypy_extensions>=0.4", "pyhdfe>=0.1", "formulaic>=1.2.1", + "packaging", ] authors = [{ name = "Kevin Sheppard", email = "kevin.k.sheppard@gmail.com" }] classifiers = [ @@ -29,6 +30,8 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.15", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", @@ -37,6 +40,7 @@ classifiers = [ "Topic :: Scientific/Engineering", ] description = "Linear Panel, Instrumental Variable, Asset Pricing, and System Regression models for Python" +# The version is set in meson.build, which runs linearmodels/_build/git_version.py dynamic = [ 'version' ] @@ -66,11 +70,12 @@ requires-python = ">=3.10" [project.optional-dependencies] test = [ # test - "pytest>=8.4.1,<9", + "pytest>=9,<10", "pytest-randomly", "pytest-xdist", "pytest-cov", "coverage[toml]", + "xarray>=0.16", # The tests import xarray "meson", "ninja", ] @@ -78,19 +83,17 @@ doc = [ # Documentation "setuptools>=61", "wheel", - "setuptools_scm[toml]>=8.0.3,<9", - "oldest-supported-numpy", - "cython>=3.0.13,<4", # Sync with CYTHON_MIN_VER in setup + "setuptools_scm[toml]>=9.2.0,<10", + "cython>=3.1.0,<4", # Sync with the Cython check in meson.build "numpy >=1.22", "scipy >=1.5.0", "ipython >=8.0.1", "matplotlib >=3.0", - "patsy >=0.5.3", "statsmodels >=0.13.5", "jinja2", "sphinx>=7", "seaborn", - "numpydoc>=1.0.0", + "numpydoc>=1.10", "nbsphinx", "sphinx-immaterial", "jupyter", @@ -98,30 +101,25 @@ doc = [ "sphinx-autodoc-typehints", "fonttools>=4.43.0", # not directly required, pinned by Snyk to avoid a vulnerability "jupyterlab>=4.4.8", # not directly required, pinned by Snyk to avoid a vulnerability - "ipython>=7", - "sphinx_immaterial", "nbconvert", "pickleshare", - # Requirements for doc build, in addition to requirements.txt - "pandas~=2.3.3", "sphinxcontrib-spelling", - "sphinx_autodoc_typehints", ] dev = [ "xarray>=0.16", - "pandas-stubsl", + "pandas-stubs", "wheel", # versioning "setuptools_scm[toml]>=9.2.0,<10", "packaging", # Performance - "cython>=3.0.10", + "cython>=3.1.0,<4", "numba>=0.55", # Graphics "matplotlib>=3", "seaborn", # Tests - "pytest>=8.4.1,<9", + "pytest>=9,<10", "pytest-randomly", "pytest-xdist", "pytest-cov", @@ -134,6 +132,7 @@ dev = [ "mypy>=1.3", "ruff>=0.16.0", "pyupgrade>=3.4.0", + "numpydoc>=1.10", # The exclude_files setting of numpydoc lint needs 1.10 "jupyterlab-code-formatter", "jupyterlab>=4.4.8", # not directly required, pinned by Snyk to avoid a vulnerability "zipp>=3.19.1", # not directly required, pinned by Snyk to avoid a vulnerability @@ -149,9 +148,6 @@ changelog = "https://bashtage.github.io/linearmodels/changes.html" [tool.meson-python.args] setup = ['--vsenv'] -[tool.setuptools_scm] -version_file = "arch/_version.py" - [tool.black] target-version = ['py310', 'py311', 'py312', 'py313', 'py314'] exclude = ''' @@ -270,10 +266,10 @@ ignore = [ "linearmodels/iv/results.py" = ["PERF203", "PLC0415"] [tool.pytest.ini_options] -minversion = "8.4.1" +minversion = "9.0" testpaths = "linearmodels" xfail_strict = true -addopts = "--strict" +strict = true empty_parameter_set_mark = "xfail" filterwarnings = [ "ignore:`formatargspec`:DeprecationWarning:statsmodels", @@ -289,7 +285,6 @@ filterwarnings = [ "error:Support for multi-dimensional indexing:DeprecationWarning", "error:multivariate_ls is deprecated:FutureWarning", "error:invalid value encountered in true_divide:RuntimeWarning", - "ignore:The --strict option is deprecated, use --strict-markers instead:pytest.PytestDeprecationWarning", "ignore:`np.bool` is a deprecated alias:DeprecationWarning:pyhdfe", "ignore:defusedxml.cElementTree:DeprecationWarning:nbconvert", "ignore:the imp module is deprecated in favour of importlib:DeprecationWarning:pywintypes", @@ -389,17 +384,19 @@ disallow_untyped_defs=true disallow_incomplete_defs=true show_error_context=true -[mypy-linearmodels.conftest] +[[tool.mypy.overrides]] +module = "linearmodels.conftest" check_untyped_defs=false disallow_untyped_defs=false -[mypy-linearmodels._version] +[[tool.mypy.overrides]] +module = "linearmodels._version" check_untyped_defs=false disallow_untyped_defs=false disallow_incomplete_defs=false [[tool.mypy.overrides]] -module = "mypy-linearmodels.tests." +module = "linearmodels.tests.*" check_untyped_defs=false disallow_untyped_defs=false disallow_incomplete_defs=false diff --git a/requirements-dev.txt b/requirements-dev.txt index ef8620faba..4ce8fcfd88 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,15 +2,15 @@ meson-python>=0.18.0 meson ninja -setuptools_scm[toml]>=8.0.3,<9 +setuptools_scm[toml]>=9.2.0,<10 packaging wheel # Performance -cython>=3.0.10 +cython>=3.1.0,<4 # Testing -pytest>=8.4.1,<9 +pytest>=9,<10 pytest-xdist pytest-cov pytest-randomly @@ -35,7 +35,7 @@ jupyterlab-code-formatter nbconvert nbformat nbsphinx -numpydoc +numpydoc>=1.10 seaborn sphinx sphinx-immaterial diff --git a/requirements.txt b/requirements.txt index 01274e83b4..467e8d0ed7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ numpy>=1.22.3,<3 pandas>=1.4.0 scipy>=1.8.0 -statsmodels>=0.13.0 +statsmodels>=0.13.1 mypy_extensions>=0.4 pyhdfe>=0.1 -formulaic>=1.0.2 -wrapt!=2.0.0rc3 \ No newline at end of file +formulaic>=1.2.1 +packaging