diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7f68be50271a1371c3c93037f16bf315abda72b5
--- /dev/null
+++ b/.github/workflows/pytest.yml
@@ -0,0 +1,36 @@
+name: Tests
+on: [push, pull_request]
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        python-version: [3.7, 3.8, 3.9, 3.10-dev]
+    steps:
+    - uses: actions/checkout@v2
+    - name: Set up Python ${{ matrix.python-version }}
+      uses: actions/setup-python@v2
+      with:
+        python-version: ${{ matrix.python-version }}
+    - name: run tests
+      env:
+        PURE_EVAL_SLOW_TESTS: 1
+      run: |
+        pip install -U pip
+        pip install --upgrade coveralls setuptools setuptools_scm pep517
+        pip install .[tests]
+        coverage run --source pure_eval -m pytest
+        coverage report -m
+    - name: Coveralls Python
+      uses: AndreMiras/coveralls-python-action@v20201129
+      with:
+        parallel: true
+        flag-name: test-${{ matrix.python-version }}
+  coveralls_finish:
+    needs: build
+    runs-on: ubuntu-latest
+    steps:
+      - name: Coveralls Finished
+        uses: AndreMiras/coveralls-python-action@v20201129
+        with:
+          parallel-finished: true
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index fb89d46ed89341affbbd025db41ee8a1e565d92c..0000000000000000000000000000000000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-dist: xenial
-language: python
-sudo: false
-
-python:
-  - 3.5
-  - 3.6
-  - 3.7
-  - 3.8-dev
-  - 3.9-dev
-
-env:
-  global:
-    - PURE_EVAL_SLOW_TESTS=1
-    - COVERALLS_PARALLEL=true
-
-before_install:
-  - pip install --upgrade coveralls setuptools>=44 setuptools_scm>=3.4.3 pep517
-
-install:
-  - pip install ".[tests]"
-
-script:
-  - coverage run --branch --include='pure_eval/*' -m pytest --junitxml=./rspec.xml
-  - coverage report -m
-
-after_success:
-  - coveralls
-
-notifications:
-  webhooks: https://coveralls.io/webhook
-  email: false
diff --git a/MANIFEST.in b/MANIFEST.in
index 42eb4101e514e6e82ecd5111fe09e81a786de694..09204c851bf40eabadb855860cc3490d5161b901 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1 +1,3 @@
 include LICENSE.txt
+include pure_eval/py.typed
+include README.md
diff --git a/make_release.sh b/make_release.sh
index 228f62810063bfd41c8d29867a2394c4a363b6ed..f0c1ac84a64f29c6b0af412ba2f0f4bc7d55a9e0 100755
--- a/make_release.sh
+++ b/make_release.sh
@@ -26,5 +26,5 @@ export TAG="v${1}"
 git tag "${TAG}"
 git push origin master "${TAG}"
 rm -rf ./build ./dist
-python3 -m pep517.build -b .
-twine upload ./dist/*.whl
+python -m build --sdist --wheel .
+twine upload ./dist/*.whl dist/*.tar.gz
diff --git a/pure_eval/core.py b/pure_eval/core.py
index 0a0381eedac208e17a213195b6e29931579d6744..748f0518d4f941c6edb1cd95bc4273ded8f14455 100644
--- a/pure_eval/core.py
+++ b/pure_eval/core.py
@@ -15,6 +15,7 @@ from pure_eval.utils import (
     of_standard_types,
     is_any,
     of_type,
+    ensure_dict,
 )
 
 
@@ -39,9 +40,9 @@ class Evaluator:
         """
 
         return cls(ChainMap(
-            frame.f_locals,
-            frame.f_globals,
-            frame.f_builtins,
+            ensure_dict(frame.f_locals),
+            ensure_dict(frame.f_globals),
+            ensure_dict(frame.f_builtins),
         ))
 
     def __getitem__(self, node: ast.expr) -> Any:
diff --git a/pure_eval/py.typed b/pure_eval/py.typed
new file mode 100644
index 0000000000000000000000000000000000000000..298c64a9041faa49413d4025444a28acc4a1f44c
--- /dev/null
+++ b/pure_eval/py.typed
@@ -0,0 +1 @@
+# Marker file for PEP 561. The pure_eval package uses inline types.
diff --git a/pure_eval/utils.py b/pure_eval/utils.py
index 139d6dd9fdd216a898943a4d86622267829dd325..a8a37302daa000d736ef9d935813892a725cbede 100644
--- a/pure_eval/utils.py
+++ b/pure_eval/utils.py
@@ -189,3 +189,13 @@ def copy_ast_without_context(x):
         return list(map(copy_ast_without_context, x))
     else:
         return x
+
+
+def ensure_dict(x):
+    """
+    Handles invalid non-dict inputs
+    """
+    try:
+        return dict(x)
+    except Exception:
+        return {}
diff --git a/setup.cfg b/setup.cfg
index 6a76979ebf517c257110f04087fc96b6b841fcf0..3d07ca911dc4a3ab22835ecf0ed70b410e697255 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -14,6 +14,7 @@ classifiers =
     Programming Language :: Python :: 3.7
     Programming Language :: Python :: 3.8
     Programming Language :: Python :: 3.9
+    Programming Language :: Python :: 3.10
     License :: OSI Approved :: MIT License
     Operating System :: OS Independent
 
@@ -22,7 +23,10 @@ packages = pure_eval
 install_requires =
 include_package_data = True
 tests_require = pytest
-setup_requires = setuptools>=44; wheel; setuptools_scm[toml]>=3.4.3
+setup_requires = setuptools>=44; setuptools_scm[toml]>=3.4.3
 
 [options.extras_require]
 tests = pytest
+
+[options.package_data]
+pure_eval = py.typed
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 315ecc5563bdf4b01379a6639a679fbbaec57494..172f50ec2c359b1ba7a7082c80e1d60c0e4ebfbe 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -17,6 +17,7 @@ from pure_eval.utils import (
     safe_name,
     typing_annotation_samples,
     is_standard_types,
+    ensure_dict,
 )
 
 
@@ -126,3 +127,10 @@ def test_is_standard_types():
     assert is_standard_types(lst, deep=False, check_dict_values=True)
     assert is_standard_types(lst[0], deep=True, check_dict_values=True)
     assert not is_standard_types(lst, deep=True, check_dict_values=True)
+
+
+def test_ensure_dict():
+    assert ensure_dict({}) == {}
+    assert ensure_dict([]) == {}
+    assert ensure_dict('foo') == {}
+    assert ensure_dict({'a': 1}) == {'a': 1}
diff --git a/tox.ini b/tox.ini
index 9f52c890325a8430ed59e2025e126a8967842288..3feff03f683bca56831bb5fedce10334559561f8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,9 +1,8 @@
 [tox]
-envlist = py{35,36,37,38,39}
+envlist = py{35,36,37,38,39,310}
 
 [testenv]
 commands = pytest
-deps =
-    .[tests]
+extras = tests
 passenv =
     PURE_EVAL_SLOW_TESTS