Skip to content
Snippets Groups Projects
Commit 9722eba1 authored by Alexander Sulfrian's avatar Alexander Sulfrian
Browse files

New upstream version 0.11.0

parents
No related branches found
No related tags found
No related merge requests found
Showing with 1571 additions and 0 deletions
# These are supported funding model platforms
github: [MatthieuDartiailh]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
\ No newline at end of file
name: Continuous Integration
on:
schedule:
- cron: '0 0 * * 3'
push:
branches:
- main
pull_request:
branches:
- main
paths:
- .github/workflows/ci.yml
- "atom/**"
- "tests/**"
- "examples/**"
- setup.py
- pyproject.toml
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.11']
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: 'lint_requirements.txt'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
- name: Install project
run: |
pip install -e .
- name: Install dependencies
run: |
pip install -U -r lint_requirements.txt
- name: Formatting
if: always()
run: |
ruff format atom examples tests --check
- name: Linting
if: always()
run: |
ruff check atom examples tests
- name: Typing
if: always()
run: |
mypy atom examples
types:
name: Type checking
runs-on: ubuntu-latest
needs:
- lint
if: needs.lint.result == 'success'
strategy:
matrix:
python-version: ['3.10']
steps:
- uses: actions/checkout@v4
- name: Get history and tags for SCM versioning to work
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
- name: Install project
run: |
pip install .
- name: Run Mypy
run: |
pip install mypy pytest
mypy atom
- name: Test with pytest
run: |
pip install pytest-mypy-plugins regex
python -X dev -m pytest tests/type_checking -v
tests:
name: Unit tests
runs-on: ${{ matrix.os }}
needs:
- lint
if: needs.lint.result == 'success'
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.10', '3.11', '3.12', '3.13-dev']
steps:
- uses: actions/checkout@v4
- name: Get history and tags for SCM versioning to work
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools-scm[toml]
pip install git+https://github.com/nucleic/cppy@main
- name: Install project
env:
CPPFLAGS: --coverage
# Build extensions manually to allow getting C coverage data
run: |
pip install -e .
- name: Test with pytest
run: |
pip install -r test_requirements.txt
python -X dev -m pytest tests --ignore=tests/type_checking --cov --cov-report xml -v -W error
- name: Generate C++ coverage reports
if: (github.event_name != 'schedule' && matrix.os != 'windows-latest')
run: |
bash -c "find . -type f -name '*.gcno' -exec gcov -pb --all-blocks {} +" || true
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: unittests
name: codecov-umbrella
fail_ci_if_error: true
verbose: true
name: Documentation building
on:
schedule:
- cron: '0 0 * * 2'
push:
branches:
- main
pull_request:
branches:
- main
paths:
- .github/workflows/docs.yml
- "atom/**"
- "docs/**"
- "examples/**"
- setup.py
- pyproject.toml
jobs:
docs:
name: Docs building
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get history and tags for SCM versioning to work
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r docs/requirements.txt
- name: Install project
run: |
pip install .
- name: Install graphviz
uses: ts-graphviz/setup-graphviz@v1
- name: Build documentation
# Remove -W till the multiple reference can be fixed in Sphinx 4
run: |
mkdir docs_output;
sphinx-build docs/source docs_output -b html;
name: Build and upload wheels
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 3'
push:
tags:
- '*'
jobs:
build_sdist:
name: Build sdist
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Get history and tags for SCM versioning to work
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Build sdist
run: |
pip install --upgrade pip
pip install wheel build
python -m build . -s
- name: Test sdist
run: |
pip install pytest
pip install dist/*.tar.gz
cd ..
python -m pytest atom/tests
- name: Store artifacts
uses: actions/upload-artifact@v4
with:
name: cibw-sdist
path: dist/*
build_wheels:
name: Build wheels on ${{ matrix.os }} for Python ${{ matrix.python }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
python: [310, 311, 312, 313]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Get history and tags for SCM versioning to work
run: |
git fetch --prune --unshallow
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install cibuildwheel
run: |
python -m pip install --upgrade pip
python -m pip install wheel cibuildwheel
- name: Build wheels
env:
# On Windows, we explicitly request MSVC compilers (as GitHub Action runners have
# MinGW on PATH that would be picked otherwise), switch to a static build for
# runtimes, but use dynamic linking for `VCRUNTIME140.dll`, `VCRUNTIME140_1.dll`,
# and the UCRT. This avoids requiring specific versions of `MSVCP140.dll`, while
# keeping shared state with the rest of the Python process/extensions.
CIBW_CONFIG_SETTINGS_WINDOWS: >-
setup-args="--vsenv"
setup-args="-Db_vscrt=mt"
setup-args="-Dcpp_link_args=['ucrt.lib','vcruntime.lib','/nodefaultlib:libucrt.lib','/nodefaultlib:libvcruntime.lib']"
CIBW_BUILD: cp${{ matrix.python }}-*
CIBW_TEST_REQUIRES: pytest
CIBW_TEST_COMMAND: python -m pytest {package}/tests -v
CIBW_ARCHS_MACOS: x86_64 universal2 arm64
run: |
python -m cibuildwheel . --output-dir dist
- name: Store artifacts
uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ runner.os }}-${{ matrix.python }}
path: dist/*.whl
publish:
if: github.event_name == 'push'
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
steps:
- name: Download all the dists
uses: actions/download-artifact@v4.1.7
with:
pattern: cibw-*
path: dist
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.pypi_password }}
# To test:
# repository_url: https://test.pypi.org/legacy/
github-release:
name: >-
Sign the Python 🐍 distribution 📦 with Sigstore
and create a GitHub Release
runs-on: ubuntu-latest
needs:
- publish
permissions:
contents: write
id-token: write
steps:
- name: Download all the dists
uses: actions/download-artifact@v4.1.7
with:
pattern: cibw-*
path: dist
merge-multiple: true
- name: Sign the dists with Sigstore
uses: sigstore/gh-action-sigstore-python@v2.1.0
with:
password: ${{ secrets.pypi_password }}
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release create
'${{ github.ref_name }}'
--repo '${{ github.repository }}'
--generate-notes
- name: Upload artifact signatures to GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release upload
'${{ github.ref_name }}' dist/**
--repo '${{ github.repository }}'
# pycharm project files
.idea
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
atom/version.py
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
reports/*
!reports/pycallgraph
!reports/pycallgraph/*
htmlcov/
cov_html/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# VS Code
.vscode
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# Data files
*.csv
# HTML files
*.html
# VSCodeCounter cache files
.VSCodeCounter
# Profiling folder used by pytest-profile
prof/
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.1.6
hooks:
# Run the linter.
- id: ruff
# Run the formatter.
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.7.0
hooks:
- id: mypy
additional_dependencies: []
\ No newline at end of file
# .readthedocs.yml# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools:
python: "3.10"
apt_packages:
- graphviz
# Build documentation in the docs/source directory with Sphinx
sphinx:
configuration: docs/source/conf.py
# Enable epub output
formats:
- epub
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt
- method: pip
path: .
LICENSE 0 → 100644
=========================
The Atom licensing terms
=========================
Atom is licensed under the terms of the Modified BSD License (also known as
New or Revised BSD), as follows:
Copyright (c) 2013-2024, Nucleic Development Team
Copyright (c) 2013, Enthought, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of the Nucleic Development Team nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
About Atom
----------
Chris Colbert began the Atom project under the umbrella of Enthought, Inc.
in February 2013. The project was forked into the Nucleic project in March
2013. Chris is still the project lead.
The Nucleic Development Team is the set of all contributors to the Nucleic
project and its subprojects.
The core team that coordinates development on GitHub can be found here:
http://github.com/nucleic. The current team consists of:
Core Developers:
* Chris Colbert
* Matthieu Dartiailh
Active Contributors:
* Steven Silvester
* Dave Willmer
Our Copyright Policy
--------------------
Nucleic uses a shared copyright model. Each contributor maintains copyright
over their contributions to Nucleic. But, it is important to note that these
contributions are typically only changes to the repositories. Thus, the Nucleic
source code, in its entirety is not the copyright of any single person or
institution. Instead, it is the collective copyright of the entire Nucleic
Development Team. If individual contributors want to maintain a record of what
changes/contributions they have specific copyright on, they should indicate
their copyright in the commit message of the change, when they commit the
change to one of the Nucleic repositories.
With this in mind, the following banner should be used in any source code file
to indicate the copyright and license terms:
#------------------------------------------------------------------------------
# Copyright (c) 2013-2024, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
#------------------------------------------------------------------------------
include MANIFEST.in
include *.txt
include *.rst
include *.md
include Makefile
include LICENSE
recursive-include docs/source *.rst
recursive-include docs/source *.png
recursive-include docs/source *.py
include docs/make.bat
include docs/Makefile
recursive-include examples *.py
recursive-include licenses *.txt
include atom/py.typed
recursive-include atom *.py
recursive-include atom *.pyi
recursive-include atom/src *.cpp
recursive-include atom/src *.h
recursive-include tests *.py
prune .git
prune docs/build
prune dist
prune build
PKG-INFO 0 → 100644
Metadata-Version: 2.1
Name: atom
Version: 0.11.0
Summary: Memory efficient Python objects
Author-email: The Nucleic Development Team <sccolbert@gmail.com>
Maintainer-email: "Matthieu C. Dartiailh" <m.dartiailh@gmail.com>
License: =========================
The Atom licensing terms
=========================
Atom is licensed under the terms of the Modified BSD License (also known as
New or Revised BSD), as follows:
Copyright (c) 2013-2024, Nucleic Development Team
Copyright (c) 2013, Enthought, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of the Nucleic Development Team nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
About Atom
----------
Chris Colbert began the Atom project under the umbrella of Enthought, Inc.
in February 2013. The project was forked into the Nucleic project in March
2013. Chris is still the project lead.
The Nucleic Development Team is the set of all contributors to the Nucleic
project and its subprojects.
The core team that coordinates development on GitHub can be found here:
http://github.com/nucleic. The current team consists of:
Core Developers:
* Chris Colbert
* Matthieu Dartiailh
Active Contributors:
* Steven Silvester
* Dave Willmer
Our Copyright Policy
--------------------
Nucleic uses a shared copyright model. Each contributor maintains copyright
over their contributions to Nucleic. But, it is important to note that these
contributions are typically only changes to the repositories. Thus, the Nucleic
source code, in its entirety is not the copyright of any single person or
institution. Instead, it is the collective copyright of the entire Nucleic
Development Team. If individual contributors want to maintain a record of what
changes/contributions they have specific copyright on, they should indicate
their copyright in the commit message of the change, when they commit the
change to one of the Nucleic repositories.
With this in mind, the following banner should be used in any source code file
to indicate the copyright and license terms:
#------------------------------------------------------------------------------
# Copyright (c) 2013-2024, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
#------------------------------------------------------------------------------
Project-URL: homepage, https://github.com/nucleic/atom
Project-URL: documentation, https://atom.readthedocs.io/en/latest/
Project-URL: repository, https://github.com/nucleic/atom
Project-URL: changelog, https://github.com/nucleic/atom/blob/main/releasenotes.rst
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Requires-Python: >=3.10
Description-Content-Type: text/x-rst
License-File: LICENSE
Requires-Dist: typing_extensions; python_version < "3.11"
Welcome to Atom
===============
.. image:: https://github.com/nucleic/atom/workflows/Continuous%20Integration/badge.svg
:target: https://github.com/nucleic/atom/actions
.. image:: https://github.com/nucleic/atom/workflows/Documentation%20building/badge.svg
:target: https://github.com/nucleic/atom/actions
.. image:: https://codecov.io/gh/nucleic/atom/branch/main/graph/badge.svg
:target: https://codecov.io/gh/nucleic/atom
.. image:: https://readthedocs.org/projects/atom/badge/?version=latest
:target: https://atom.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
:target: https://github.com/astral-sh/ruff
:alt: Ruff
Atom is a framework for creating memory efficient Python objects with enhanced
features such as dynamic initialization, validation, and change notification for
object attributes. It provides the default model binding behavior for the
`Enaml <https://enaml.readthedocs.io/en/latest/>`_ UI framework.
Examples:
.. code-block:: python
from atom.api import Atom, Str, Range, Bool, observe
class Person(Atom):
""" A simple class representing a person object.
"""
last_name = Str()
first_name = Str()
age = Range(low=0)
debug = Bool(False)
@observe('age')
def debug_print(self, change):
""" Prints out a debug message whenever the person's age changes.
"""
if self.debug:
templ = "{first} {last} is {age} years old."
s = templ.format(
first=self.first_name, last=self.last_name, age=self.age,
)
print(s)
def _default_first_name(self):
return 'John'
john = Person(last_name='Doe', age=42)
john.debug = True
john.age = 43 # prints message
john.age = 'forty three' # raises TypeError
Starting with atom 0.8.0 atom object can also be defined using type annotations.
.. code-block:: python
from atom.api import Atom, observe
class InventoryItem(Atom):
"""Class for keeping track of an item in inventory."""
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
@observe("unit_price")
def check_for_price_reduction(self, change):
savings = change.get("oldvalue", 0) - change.get("value")
if savings > 0:
print(f"Save ${savings} now on {self.name}s!")
>>> w = InventoryItem(name="widget", unit_price=1.99, quantity_on_hand=10)
>>> w.unit_price = 1.00
Save $0.99 now on widgets!
For version information, see `the Revision History <https://github.com/nucleic/atom/blob/main/releasenotes.rst>`_.
Welcome to Atom
===============
.. image:: https://github.com/nucleic/atom/workflows/Continuous%20Integration/badge.svg
:target: https://github.com/nucleic/atom/actions
.. image:: https://github.com/nucleic/atom/workflows/Documentation%20building/badge.svg
:target: https://github.com/nucleic/atom/actions
.. image:: https://codecov.io/gh/nucleic/atom/branch/main/graph/badge.svg
:target: https://codecov.io/gh/nucleic/atom
.. image:: https://readthedocs.org/projects/atom/badge/?version=latest
:target: https://atom.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
:target: https://github.com/astral-sh/ruff
:alt: Ruff
Atom is a framework for creating memory efficient Python objects with enhanced
features such as dynamic initialization, validation, and change notification for
object attributes. It provides the default model binding behavior for the
`Enaml <https://enaml.readthedocs.io/en/latest/>`_ UI framework.
Examples:
.. code-block:: python
from atom.api import Atom, Str, Range, Bool, observe
class Person(Atom):
""" A simple class representing a person object.
"""
last_name = Str()
first_name = Str()
age = Range(low=0)
debug = Bool(False)
@observe('age')
def debug_print(self, change):
""" Prints out a debug message whenever the person's age changes.
"""
if self.debug:
templ = "{first} {last} is {age} years old."
s = templ.format(
first=self.first_name, last=self.last_name, age=self.age,
)
print(s)
def _default_first_name(self):
return 'John'
john = Person(last_name='Doe', age=42)
john.debug = True
john.age = 43 # prints message
john.age = 'forty three' # raises TypeError
Starting with atom 0.8.0 atom object can also be defined using type annotations.
.. code-block:: python
from atom.api import Atom, observe
class InventoryItem(Atom):
"""Class for keeping track of an item in inventory."""
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
@observe("unit_price")
def check_for_price_reduction(self, change):
savings = change.get("oldvalue", 0) - change.get("value")
if savings > 0:
print(f"Save ${savings} now on {self.name}s!")
>>> w = InventoryItem(name="widget", unit_price=1.99, quantity_on_hand=10)
>>> w.unit_price = 1.00
Save $0.99 now on widgets!
For version information, see `the Revision History <https://github.com/nucleic/atom/blob/main/releasenotes.rst>`_.
Metadata-Version: 2.1
Name: atom
Version: 0.11.0
Summary: Memory efficient Python objects
Author-email: The Nucleic Development Team <sccolbert@gmail.com>
Maintainer-email: "Matthieu C. Dartiailh" <m.dartiailh@gmail.com>
License: =========================
The Atom licensing terms
=========================
Atom is licensed under the terms of the Modified BSD License (also known as
New or Revised BSD), as follows:
Copyright (c) 2013-2024, Nucleic Development Team
Copyright (c) 2013, Enthought, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
Neither the name of the Nucleic Development Team nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
About Atom
----------
Chris Colbert began the Atom project under the umbrella of Enthought, Inc.
in February 2013. The project was forked into the Nucleic project in March
2013. Chris is still the project lead.
The Nucleic Development Team is the set of all contributors to the Nucleic
project and its subprojects.
The core team that coordinates development on GitHub can be found here:
http://github.com/nucleic. The current team consists of:
Core Developers:
* Chris Colbert
* Matthieu Dartiailh
Active Contributors:
* Steven Silvester
* Dave Willmer
Our Copyright Policy
--------------------
Nucleic uses a shared copyright model. Each contributor maintains copyright
over their contributions to Nucleic. But, it is important to note that these
contributions are typically only changes to the repositories. Thus, the Nucleic
source code, in its entirety is not the copyright of any single person or
institution. Instead, it is the collective copyright of the entire Nucleic
Development Team. If individual contributors want to maintain a record of what
changes/contributions they have specific copyright on, they should indicate
their copyright in the commit message of the change, when they commit the
change to one of the Nucleic repositories.
With this in mind, the following banner should be used in any source code file
to indicate the copyright and license terms:
#------------------------------------------------------------------------------
# Copyright (c) 2013-2024, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
#------------------------------------------------------------------------------
Project-URL: homepage, https://github.com/nucleic/atom
Project-URL: documentation, https://atom.readthedocs.io/en/latest/
Project-URL: repository, https://github.com/nucleic/atom
Project-URL: changelog, https://github.com/nucleic/atom/blob/main/releasenotes.rst
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Requires-Python: >=3.10
Description-Content-Type: text/x-rst
License-File: LICENSE
Requires-Dist: typing_extensions; python_version < "3.11"
Welcome to Atom
===============
.. image:: https://github.com/nucleic/atom/workflows/Continuous%20Integration/badge.svg
:target: https://github.com/nucleic/atom/actions
.. image:: https://github.com/nucleic/atom/workflows/Documentation%20building/badge.svg
:target: https://github.com/nucleic/atom/actions
.. image:: https://codecov.io/gh/nucleic/atom/branch/main/graph/badge.svg
:target: https://codecov.io/gh/nucleic/atom
.. image:: https://readthedocs.org/projects/atom/badge/?version=latest
:target: https://atom.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
:target: https://github.com/astral-sh/ruff
:alt: Ruff
Atom is a framework for creating memory efficient Python objects with enhanced
features such as dynamic initialization, validation, and change notification for
object attributes. It provides the default model binding behavior for the
`Enaml <https://enaml.readthedocs.io/en/latest/>`_ UI framework.
Examples:
.. code-block:: python
from atom.api import Atom, Str, Range, Bool, observe
class Person(Atom):
""" A simple class representing a person object.
"""
last_name = Str()
first_name = Str()
age = Range(low=0)
debug = Bool(False)
@observe('age')
def debug_print(self, change):
""" Prints out a debug message whenever the person's age changes.
"""
if self.debug:
templ = "{first} {last} is {age} years old."
s = templ.format(
first=self.first_name, last=self.last_name, age=self.age,
)
print(s)
def _default_first_name(self):
return 'John'
john = Person(last_name='Doe', age=42)
john.debug = True
john.age = 43 # prints message
john.age = 'forty three' # raises TypeError
Starting with atom 0.8.0 atom object can also be defined using type annotations.
.. code-block:: python
from atom.api import Atom, observe
class InventoryItem(Atom):
"""Class for keeping track of an item in inventory."""
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
@observe("unit_price")
def check_for_price_reduction(self, change):
savings = change.get("oldvalue", 0) - change.get("value")
if savings > 0:
print(f"Save ${savings} now on {self.name}s!")
>>> w = InventoryItem(name="widget", unit_price=1.99, quantity_on_hand=10)
>>> w.unit_price = 1.00
Save $0.99 now on widgets!
For version information, see `the Revision History <https://github.com/nucleic/atom/blob/main/releasenotes.rst>`_.
.gitignore
.pre-commit-config.yaml
.readthedocs.yaml
LICENSE
MANIFEST.in
README.rst
codecov.yml
lint_requirements.txt
pyproject.toml
releasenotes.rst
setup.py
test_requirements.txt
.github/FUNDING.yml
.github/dependabot.yml
.github/workflows/ci.yml
.github/workflows/docs.yml
.github/workflows/release.yml
atom/__init__.py
atom/api.py
atom/atom.py
atom/catom.pyi
atom/coerced.py
atom/coerced.pyi
atom/containerlist.py
atom/containerlist.pyi
atom/delegator.py
atom/delegator.pyi
atom/dict.py
atom/dict.pyi
atom/enum.py
atom/enum.pyi
atom/event.py
atom/event.pyi
atom/instance.py
atom/instance.pyi
atom/list.py
atom/list.pyi
atom/property.py
atom/property.pyi
atom/py.typed
atom/scalars.py
atom/scalars.pyi
atom/set.py
atom/set.pyi
atom/signal.py
atom/signal.pyi
atom/subclass.py
atom/subclass.pyi
atom/tuple.py
atom/tuple.pyi
atom/typed.py
atom/typed.pyi
atom/typing_utils.py
atom/version.py
atom.egg-info/PKG-INFO
atom.egg-info/SOURCES.txt
atom.egg-info/dependency_links.txt
atom.egg-info/requires.txt
atom.egg-info/top_level.txt
atom/datastructures/__init__.py
atom/datastructures/api.py
atom/datastructures/sortedmap.pyi
atom/meta/__init__.py
atom/meta/annotation_utils.py
atom/meta/atom_meta.py
atom/meta/member_modifiers.py
atom/meta/observation.py
atom/src/atomdict.cpp
atom/src/atomdict.h
atom/src/atomlist.cpp
atom/src/atomlist.h
atom/src/atomref.cpp
atom/src/atomref.h
atom/src/atomset.cpp
atom/src/atomset.h
atom/src/behaviors.h
atom/src/catom.cpp
atom/src/catom.h
atom/src/catommodule.cpp
atom/src/catompointer.h
atom/src/defaultvaluebehavior.cpp
atom/src/delattrbehavior.cpp
atom/src/enumtypes.cpp
atom/src/enumtypes.h
atom/src/eventbinder.cpp
atom/src/eventbinder.h
atom/src/getattrbehavior.cpp
atom/src/getstatebehavior.cpp
atom/src/globalstatic.h
atom/src/member.cpp
atom/src/member.h
atom/src/memberchange.cpp
atom/src/memberchange.h
atom/src/methodwrapper.cpp
atom/src/methodwrapper.h
atom/src/modifyguard.h
atom/src/msstdint.h
atom/src/observer.h
atom/src/observerpool.cpp
atom/src/observerpool.h
atom/src/packagenaming.h
atom/src/platstdint.h
atom/src/postgetattrbehavior.cpp
atom/src/postsetattrbehavior.cpp
atom/src/postvalidatebehavior.cpp
atom/src/propertyhelper.cpp
atom/src/propertyhelper.h
atom/src/setattrbehavior.cpp
atom/src/signalconnector.cpp
atom/src/signalconnector.h
atom/src/sortedmap.cpp
atom/src/utils.h
atom/src/validatebehavior.cpp
docs/Makefile
docs/make.bat
docs/requirements.txt
docs/source/conf.py
docs/source/index.rst
docs/source/substitutions.sub
docs/source/advanced/containers.rst
docs/source/advanced/customization.rst
docs/source/advanced/index.rst
docs/source/advanced/manual_notifications.rst
docs/source/advanced/property.rst
docs/source/advanced/typing.rst
docs/source/advanced/weakref.rst
docs/source/api/atom.api.rst
docs/source/api/atom.atom.rst
docs/source/api/atom.catom.rst
docs/source/api/atom.coerced.rst
docs/source/api/atom.containerlist.rst
docs/source/api/atom.datastructures.rst
docs/source/api/atom.delegator.rst
docs/source/api/atom.dict.rst
docs/source/api/atom.enum.rst
docs/source/api/atom.event.rst
docs/source/api/atom.instance.rst
docs/source/api/atom.list.rst
docs/source/api/atom.meta.rst
docs/source/api/atom.property.rst
docs/source/api/atom.rst
docs/source/api/atom.scalars.rst
docs/source/api/atom.signal.rst
docs/source/api/atom.subclass.rst
docs/source/api/atom.tuple.rst
docs/source/api/atom.typed.rst
docs/source/api/atom.typing_utils.rst
docs/source/basis/basis.rst
docs/source/basis/index.rst
docs/source/basis/installation.rst
docs/source/basis/mangled_methods.rst
docs/source/basis/members.rst
docs/source/basis/observation.rst
docs/source/basis/typing.rst
docs/source/developer_notes/index.rst
docs/source/examples/ex_coersion.rst
docs/source/examples/ex_composition.rst
docs/source/examples/ex_containers.rst
docs/source/examples/ex_default_value.rst
docs/source/examples/ex_employee.rst
docs/source/examples/ex_hello_world.rst
docs/source/examples/ex_inventory.rst
docs/source/examples/ex_metadata.rst
docs/source/examples/ex_numeric.rst
docs/source/examples/ex_observe.rst
docs/source/examples/ex_observe_hints.rst
docs/source/examples/ex_person.rst
docs/source/examples/ex_pickling.rst
docs/source/examples/ex_property.rst
docs/source/examples/ex_range.rst
docs/source/examples/ex_static_type_checking.rst
docs/source/examples/example_doc_generator.py
docs/source/examples/index.rst
examples/api/coersion.py
examples/api/composition.py
examples/api/containers.py
examples/api/default_value.py
examples/api/metadata.py
examples/api/numeric.py
examples/api/observe.py
examples/api/observe_hints.py
examples/api/pickling.py
examples/api/property.py
examples/api/range.py
examples/tutorial/employee.py
examples/tutorial/hello_world.py
examples/tutorial/person.py
examples/typehints/inventory.py
examples/typehints/static_type_checking.py
tests/test_atom.py
tests/test_atom_from_annotations.py
tests/test_atomdefaultdict.py
tests/test_atomdict.py
tests/test_atomlist.py
tests/test_atomref.py
tests/test_atomset.py
tests/test_default_values.py
tests/test_del_behaviors.py
tests/test_delegator.py
tests/test_enum.py
tests/test_eventbinder.py
tests/test_examples.py
tests/test_get_behaviors.py
tests/test_get_set_state.py
tests/test_getstate_behaviors.py
tests/test_mem.py
tests/test_member.py
tests/test_observe.py
tests/test_post_behaviors.py
tests/test_property.py
tests/test_set_behaviors.py
tests/test_signalconnector.py
tests/test_typing_utils.py
tests/test_validators.py
tests/test_version.py
tests/datastructure/test_sortedmap.py
tests/type_checking/test_annotations.yml
tests/type_checking/test_coerced.yml
tests/type_checking/test_delegator.yml
tests/type_checking/test_dict.yml
tests/type_checking/test_enum.yml
tests/type_checking/test_event.yml
tests/type_checking/test_generic_aliases.yml
tests/type_checking/test_list.yml
tests/type_checking/test_property.yml
tests/type_checking/test_scalars.yml
tests/type_checking/test_set.yml
tests/type_checking/test_signal.yml
tests/type_checking/test_subclass.yml
tests/type_checking/test_tuple.yml
tests/type_checking/test_typed_instance.yml
\ No newline at end of file
[:python_version < "3.11"]
typing_extensions
atom
# --------------------------------------------------------------------------------------
# Copyright (c) 2013-2024, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Copyright (c) 2013-2024, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# --------------------------------------------------------------------------------------
"""Module exporting the public interface to atom."""
from .atom import Atom
from .catom import (
CAtom,
ChangeType,
DefaultValue,
GetAttr,
GetState,
Member,
PostGetAttr,
PostSetAttr,
PostValidate,
SetAttr,
Validate,
atomclist,
atomdict,
atomlist,
atomref,
atomset,
defaultatomdict,
)
from .coerced import Coerced
from .containerlist import ContainerList
from .delegator import Delegator
from .dict import DefaultDict, Dict
from .enum import Enum
from .event import Event
from .instance import ForwardInstance, Instance
from .list import List
from .meta import (
AtomMeta,
MissingMemberWarning,
add_member,
clone_if_needed,
observe,
set_default,
)
from .property import Property, cached_property
from .scalars import (
Bool,
Bytes,
Callable,
Constant,
Float,
FloatRange,
Int,
Range,
ReadOnly,
Str,
Value,
)
from .set import Set
from .signal import Signal
from .subclass import ForwardSubclass, Subclass
from .tuple import FixedTuple, Tuple
from .typed import ForwardTyped, Typed
from .typing_utils import ChangeDict
__all__ = [
"Atom",
"AtomMeta",
"MissingMemberWarning",
"add_member",
"observe",
"set_default",
"clone_if_needed",
"CAtom",
"ChangeType",
"DefaultValue",
"GetAttr",
"GetState",
"Member",
"PostGetAttr",
"PostSetAttr",
"PostValidate",
"SetAttr",
"Validate",
"atomclist",
"atomdict",
"defaultatomdict",
"atomlist",
"atomref",
"atomset",
"Coerced",
"ContainerList",
"Delegator",
"Dict",
"DefaultDict",
"Enum",
"Event",
"ForwardInstance",
"Instance",
"List",
"Property",
"cached_property",
"Bool",
"Bytes",
"Callable",
"Constant",
"Float",
"FloatRange",
"Int",
"Range",
"ReadOnly",
"Str",
"Value",
"Set",
"Signal",
"ForwardSubclass",
"Subclass",
"Tuple",
"ForwardTyped",
"Typed",
"FixedTuple",
"ChangeDict",
]
# --------------------------------------------------------------------------------------
# Copyright (c) 2013-2024, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# --------------------------------------------------------------------------------------
from contextlib import contextmanager
from typing import ClassVar, Iterator, Mapping
from .catom import CAtom, Member
from .meta import AtomMeta, add_member, observe, set_default # noqa
# The above are imported to avoid breaking code relying on internals
def __newobj__(cls, *args):
"""A compatibility pickler function.
This function is not part of the public Atom api.
"""
return cls.__new__(cls, *args)
class Atom(CAtom, metaclass=AtomMeta):
"""The base class for defining atom objects.
`Atom` objects are special Python objects which never allocate an
instance dictionary unless one is explicitly requested. The storage
for an atom is instead computed from the `Member` objects declared
on the class. Memory is reserved for these members with no over
allocation.
This restriction make atom objects a bit less flexible than normal
Python objects, but they are between 3x-10x more memory efficient
than normal objects depending on the number of attributes.
"""
__atom_members__: ClassVar[Mapping[str, Member]]
@classmethod
def members(cls) -> Mapping[str, Member]:
"""Get the members dictionary for the type.
Returns
-------
result : Mapping[str, Member]
The dictionary of members defined on the class. User code
should not modify the contents of the dict.
"""
return cls.__atom_members__
@contextmanager
def suppress_notifications(self) -> Iterator[None]:
"""Disable member notifications within in a context.
Returns
-------
result : contextmanager
A context manager which disables atom notifications for the
duration of the context. When the context exits, the state
is restored to its previous value.
"""
old = self.set_notifications_enabled(False)
yield
self.set_notifications_enabled(old)
def __reduce_ex__(self, proto):
"""An implementation of the reduce protocol.
This method creates a reduction tuple for Atom instances. This
method should not be overridden by subclasses unless the author
fully understands the rammifications.
"""
args = (type(self), *self.__getnewargs__())
return (__newobj__, args, self.__getstate__())
def __getnewargs__(self):
"""Get the argument tuple to pass to __new__ on unpickling.
See the Python.org docs for more information.
"""
return ()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment