diff --git a/CHANGES.rst b/CHANGES.rst
index d089805..77d7934 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -13,6 +13,9 @@ Change History for ZConfig
 
 - BaseLoader is now an abstract class that cannot be instantiated.
 
+- Allow ``nan``, ``inf`` and ``-inf`` values for floats in
+  configurations. See https://github.com/zopefoundation/ZConfig/issues/16.
+
 3.1.0 (2015-10-17)
 ------------------
 
diff --git a/ZConfig/datatypes.py b/ZConfig/datatypes.py
index 1b33ecb..3dce2ef 100644
--- a/ZConfig/datatypes.py
+++ b/ZConfig/datatypes.py
@@ -280,13 +280,9 @@ class SocketConnectionAddress(SocketAddress):
 
 
 def float_conversion(v):
-    # float() will accept both bytes and unicode on both 2 and 3
-    is_str = isinstance(v, text_type) or isinstance(v, binary_type)
-    if is_str:
-        if v.lower() in (u"inf", u"-inf", u"nan", b'inf', b'-inf', b'nan'):
-            raise ValueError(repr(v) + " is not a portable float representation")
     return float(v)
 
+
 class IpaddrOrHostname(RegularExpressionConversion):
     def __init__(self):
         # IP address regex from the Perl Cookbook, Recipe 6.23 (revised ed.)

Simplify float conversion
See https://github.com/zopefoundation/ZConfig/pull/13#discussion_r100796977
diff --git a/ZConfig/tests/support.py b/ZConfig/tests/support.py
index 6094455..c583f97 100644
--- a/ZConfig/tests/support.py
+++ b/ZConfig/tests/support.py
@@ -24,12 +24,6 @@ from ZConfig.url import urljoin
 from ZConfig._compat import NStringIO as StringIO
 from ZConfig._compat import pathname2url
 
-try:
-    __file__
-except NameError: # pragma: no cover
-    import sys
-    __file__ = sys.argv[0]
-
 d = os.path.abspath(os.path.join(os.path.dirname(__file__), "input"))
 CONFIG_BASE = "file://%s/" % pathname2url(d)
 
diff --git a/ZConfig/tests/test_datatypes.py b/ZConfig/tests/test_datatypes.py
index 9ee8778..9419e74 100644
--- a/ZConfig/tests/test_datatypes.py
+++ b/ZConfig/tests/test_datatypes.py
@@ -23,12 +23,7 @@ import unittest
 
 import ZConfig.datatypes
 
-try:
-    here = __file__
-except NameError: # pragma: no cover
-    here = sys.argv[0]
-
-here = os.path.abspath(here)
+here = os.path.abspath(__file__)
 
 try:
     unicode
@@ -91,15 +86,15 @@ class DatatypeTestCase(unittest.TestCase):
         raises(ValueError, convert, "0x234.1.9")
         raises(ValueError, convert, "0.9-")
 
-        # These are not portable representations; make sure they are
-        # disallowed everywhere for consistency.
-        raises(ValueError, convert, b"inf")
-        raises(ValueError, convert, b"-inf")
-        raises(ValueError, convert, b"nan")
+        # float handles inf/nan portably in both bytes and
+        # unicode on both Python 2.6+ and Python 3. Make sure conversion
+        # does too.
+        for literal in ("inf", "-inf", b"inf", b"-inf"):
+            eq(convert(literal), float(literal))
 
-        raises(ValueError, convert, u"inf")
-        raises(ValueError, convert, u"-inf")
-        raises(ValueError, convert, u"nan")
+        # notably, nan is not equal to itself
+        self.assertNotEqual(convert("nan"), float("nan"))
+        self.assertNotEqual(convert(b"nan"), float(b"nan"))
 
     def test_datatype_identifier(self):
         convert = self.types.get("identifier")
diff --git a/ZConfig/tests/test_loader.py b/ZConfig/tests/test_loader.py
index 3ca5c66..b30505f 100644
--- a/ZConfig/tests/test_loader.py
+++ b/ZConfig/tests/test_loader.py
@@ -28,12 +28,7 @@ from ZConfig._compat import urllib2
 from ZConfig.tests.support import CONFIG_BASE, TestHelper
 
 
-try:
-    myfile = __file__
-except NameError: # pragma: no cover
-    myfile = sys.argv[0]
-
-myfile = os.path.abspath(myfile)
+myfile = os.path.abspath(__file__)
 LIBRARY_DIR = os.path.join(os.path.dirname(myfile), "library")
 
 

pip install -e .[test]
parse_log_pytest
requirements.txt
zope.testrunner nose coverage nosexcover pytest
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
coverage==7.8.0
exceptiongroup==1.2.2
iniconfig==2.1.0
nose==1.3.7
nosexcover==1.0.11
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
tomli==2.2.1
-e git+https://github.com/zopefoundation/ZConfig.git@010cb2b2d4d2cdc8cd327f9f46a987024cac5b67#egg=ZConfig
zope.exceptions==5.2
zope.interface==7.2
zope.testrunner==7.2

name: ZConfig
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - coverage==7.8.0
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - nose==1.3.7
      - nosexcover==1.0.11
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - tomli==2.2.1
      - zope-exceptions==5.2
      - zope-interface==7.2
      - zope-testrunner==7.2
prefix: /opt/conda/envs/ZConfig

ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_float
ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_byte_size ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_basickey ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_boolean ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_dotted_name ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_dotted_suffix ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_identifier ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_inet_address ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_inet_binding_address ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_inet_connection_address ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_integer ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_locale ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_port ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_datatype_socket_address ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_existing_directory ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_existing_dirpath ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_existing_file ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_existing_path ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_ipaddr_or_hostname ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_time_interval ZConfig/tests/test_datatypes.py::DatatypeTestCase::test_timedelta ZConfig/tests/test_datatypes.py::RegistryTestCase::test_get_fallback_basic_key ZConfig/tests/test_datatypes.py::RegistryTestCase::test_register_shadow ZConfig/tests/test_datatypes.py::RegistryTestCase::test_registry_does_not_mask_toplevel_imports ZConfig/tests/test_datatypes.py::test_suite ZConfig/tests/test_loader.py::LoaderTestCase::test_config_loader_abstract_schema ZConfig/tests/test_loader.py::LoaderTestCase::test_file_url_normalization ZConfig/tests/test_loader.py::LoaderTestCase::test_import_component_twice_1 ZConfig/tests/test_loader.py::LoaderTestCase::test_import_component_twice_2 ZConfig/tests/test_loader.py::LoaderTestCase::test_import_errors ZConfig/tests/test_loader.py::LoaderTestCase::test_import_from_package ZConfig/tests/test_loader.py::LoaderTestCase::test_import_from_package_extra_directory ZConfig/tests/test_loader.py::LoaderTestCase::test_import_from_package_with_directory_file ZConfig/tests/test_loader.py::LoaderTestCase::test_import_from_package_with_file ZConfig/tests/test_loader.py::LoaderTestCase::test_import_from_package_with_missing_file ZConfig/tests/test_loader.py::LoaderTestCase::test_import_two_components_one_package ZConfig/tests/test_loader.py::LoaderTestCase::test_isPath ZConfig/tests/test_loader.py::LoaderTestCase::test_schema_caching ZConfig/tests/test_loader.py::LoaderTestCase::test_schema_loader_source_errors ZConfig/tests/test_loader.py::LoaderTestCase::test_simple_import_using_prefix ZConfig/tests/test_loader.py::LoaderTestCase::test_simple_import_with_cache ZConfig/tests/test_loader.py::LoaderTestCase::test_url_from_file ZConfig/tests/test_loader.py::LoaderTestCase::test_urlsplit_urlunsplit ZConfig/tests/test_loader.py::TestNonExistentResources::test_nonexistent_file_ioerror ZConfig/tests/test_loader.py::TestNonExistentResources::test_nonexistent_file_oserror ZConfig/tests/test_loader.py::TestResourcesInZip::test_zip_import_component_from_config ZConfig/tests/test_loader.py::TestResourcesInZip::test_zip_import_component_from_schema ZConfig/tests/test_loader.py::TestOpenPackageResource::test_package_loader_resource_error ZConfig/tests/test_loader.py::TestOpenPackageResource::test_resource ZConfig/tests/test_loader.py::test_suite
ZConfig/datatypes.py CHANGES.rst
ZConfig/datatypes.py CHANGES.rst