33 Commits
v0.1.0 ... main

Author SHA1 Message Date
0556d32cfb release: v0.1.2
All checks were successful
Upload to PyPI / publish (push) Successful in 3m51s
Deploy Sphinx Docs / build-and-deploy (push) Successful in 1m54s
2026-02-12 16:24:49 +08:00
7575283c69 feat: add simplified methods for get_primitive_object to package root
Now you can import them from path `primitive_type` immediately.
2026-02-12 16:23:31 +08:00
ff5c2ebfca release: v0.1.1
All checks were successful
Upload to PyPI / publish (push) Successful in 49s
Deploy Sphinx Docs / build-and-deploy (push) Successful in 2m17s
Right commit.
2026-02-12 15:25:10 +08:00
bd4279e920 release: v0.1.1 2026-02-12 15:20:41 +08:00
394d5bc503 docs(ci): try fix translation link targets in cloudflare
All checks were successful
Deploy Sphinx Docs / build-and-deploy (push) Successful in 2m12s
2026-02-12 14:22:03 +08:00
df40d98b5b docs(ci): build new docs
All checks were successful
Deploy Sphinx Docs / build-and-deploy (push) Successful in 1m58s
2026-02-12 14:15:30 +08:00
c70b7eb8d0 docs(ci): try trigger error in remove note stage
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Failing after 1m2s
2026-02-12 14:12:47 +08:00
f0edde1e02 docs(ci): remove note i18n for local test
All checks were successful
Deploy Sphinx Docs / build-and-deploy (push) Successful in 2m8s
2026-02-12 14:06:08 +08:00
14fc4f8282 feat: add simplified methods for get_primitive_object
All checks were successful
Deploy Sphinx Docs / build-and-deploy (push) Successful in 2m15s
2026-02-12 13:56:15 +08:00
0ce2e94ed7 docs(ci): test ci network
All checks were successful
Deploy Sphinx Docs / build-and-deploy (push) Successful in 2m16s
2026-02-11 11:22:01 +08:00
cb6e33d834 docs(ci): try fix
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Has been cancelled
2026-02-11 11:04:52 +08:00
14ff731fa3 docs(ci): test job runner network
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Failing after 29s
2026-02-11 11:00:54 +08:00
002df5d6ac chore: delete useless files 2026-02-11 00:33:39 +08:00
81a6c7bd88 docs(ci): fix
All checks were successful
Deploy Sphinx Docs / build-and-deploy (push) Successful in 12m44s
2026-02-10 22:31:35 +08:00
2bd1dce74c docs(ci): fix
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Failing after 9m2s
2026-02-10 22:11:27 +08:00
1a73e8bd02 docs(ci): fix
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Failing after 15m31s
2026-02-10 21:32:24 +08:00
d4fec71f39 docs(ci): fix deployment
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Failing after 9m24s
2026-02-10 21:17:42 +08:00
726e7f97fa docs(ci): add nodejs v20 require
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Failing after 13m21s
2026-02-10 20:40:59 +08:00
0b694013ad docs(ci): trigger workflow
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Failing after 6m59s
2026-02-10 20:00:57 +08:00
47e53c750b docs(ci): fix workflow configs
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Has been cancelled
2026-02-10 17:34:44 +08:00
3104d48cec docs(ci): trigger workflow
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Failing after 54s
2026-02-10 17:16:20 +08:00
1062ef9303 docs(ci): pre-install nodejs for checkout codes 2026-02-10 17:14:43 +08:00
354efdaef5 docs(ci): trigger deployment to Cloudflare
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Failing after 55s
2026-02-10 17:10:05 +08:00
623b60612b docs(ci!): use cloudflare worker instead 2026-02-10 17:06:16 +08:00
2cf7028868 docs(ci): (fix:workflow) correct runner label 2026-02-10 16:18:32 +08:00
73be4ed075 docs(ci): prepare deployment to cloudflare
Some checks failed
Deploy Sphinx Docs / build-and-deploy (push) Has been cancelled
2026-02-10 16:15:29 +08:00
7aa947fce0 docs(feat): finish documentation
Go also https://docs.staringplanet.top/primitive-type later to see the
docs later.
2026-02-10 12:55:16 +08:00
6dc9bafc3f chore: make clean_pycache.py script executable 2026-02-10 10:09:10 +08:00
183beacff6 chore: add dev tools to uv env 2026-02-10 10:00:39 +08:00
c5be89305a chore: add a simple script to clean __pycache__ quickly 2026-02-10 09:58:06 +08:00
0c6b92ceeb chore: (fix:uv) fix wrong in denpendency-groups 2026-02-09 15:19:58 +08:00
41d4a85374 chore(uv): add build dependencies 2026-02-09 15:12:52 +08:00
b0a79bb0c7 feat: test Python 3.14 is ok 2026-02-09 15:06:56 +08:00
25 changed files with 1221 additions and 6 deletions

View File

@@ -0,0 +1,66 @@
name: Deploy Sphinx Docs
on:
push:
branches:
- main
paths:
- "docs/**"
- "pyproject.toml"
- ".gitea/workflows/deploy-docs.yaml"
paths-ignore:
- "**.sh"
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Checkout version
uses: actions/checkout@v4
- name: Setup uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
- name: Setup Python
run: uv python install 3.12
- name: Install Dependencies
run: |
uv sync --all-groups --no-progress
- name: Remove note i18n for local test
run: |
cd docs
FILE="source/index.rst"
if [ ! -f "$FILE" ]; then
echo "ERROR: $FILE not found!"
exit 1
fi
perl -0777 -i -pe 's/\.\. note::\s+\|NOTE_I18N\|\n//g' source/index.rst
cd ..
- name: Build Sphinx Documentation
run: |
cd docs
uv run ./build_docs.sh
uv run ./build_docs.sh zh_CN
echo "Copying builds..."
mkdir -p ../public
mkdir -p ../public/zh_CN
cp -r build/html/* ../public/
cp -r build/html_zh_CN/* ../public/zh_CN/
cd ..
- name: Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
# command: deploy --config wrangler.jsonc
command: pages deploy public --project-name=primitive-type-pydocs --branch=main

View File

@@ -0,0 +1,31 @@
name: Upload to PyPI
on:
push:
tags:
- "v*"
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
- name: Set up Python
run: uv python install 3.12
- name: Run tests
run: uv run python -m unittest discover tests
- name: Build package
run: uv build
- name: Publish to PyPI
env:
UV_PUBLISH_TOKEN: ${{ secrets.UV_PUBLISH_TOKEN }}
run: uv publish

View File

@@ -1,3 +1,8 @@
# primitive-type
Check a value or object if the type of it is primitive, or convert it to other primitive type in Python.
Check a value or object if the type of it is primitive,
or convert it to other primitive type in Python.
See the [Docs](https://docs.staringplanet.top/primitive-type) for more informations.
> If the link is unreachable, go <https://primitive-type-pydocs.pages.dev>

37
clean_pycache.py Executable file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/env python3
import os
import shutil
import sys
def remove_pycache_dirs(start_dir="."):
removed_count = 0
for root, dirs, files in os.walk(start_dir, topdown=True):
if ".venv" in dirs:
dirs.remove(".venv")
if ".git" in dirs:
dirs.remove(".git")
if "__pycache__" in dirs:
pycache_path = os.path.join(root, "__pycache__")
try:
shutil.rmtree(pycache_path)
print(f"Deleted: {pycache_path}")
removed_count += 1
except Exception as e:
print(f"Failed to delete {pycache_path}: {e}")
print(f"\nTotally deleted {removed_count} __pycache__ folders.")
if __name__ == "__main__":
target_dir = sys.argv[1] if len(sys.argv) > 1 else "."
print(f"Scanning directory: {os.path.abspath(target_dir)}")
confirm = input("Are you sure to delete all __pycache__ folders? (y/N): ")
if confirm.lower() == "y":
remove_pycache_dirs(target_dir)
else:
print("Option cancelled.")

20
docs/Makefile Normal file
View File

@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

11
docs/build_docs.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
LANG_CODE=$1
if [ -n "$LANG_CODE" ]; then
echo "Building docs for language: $LANG_CODE..."
sphinx-build -b html source/ "build/html_$LANG_CODE/" -D language="$LANG_CODE"
else
echo "Building docs in English (en_US)..."
sphinx-build -b html source build/html
fi

35
docs/make.bat Normal file
View File

@@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

11
docs/serve_docs.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
LANG_CODE=$1
if [ -n "$LANG_CODE" ]; then
echo "Starting docs preview for language: $LANG_CODE..."
sphinx-autobuild -D language="$LANG_CODE" --port 8000 source/ "build/html_$LANG_CODE/"
else
echo "Starting docs preview in English (en_US)..."
sphinx-autobuild --port 8000 source/ build/html/
fi

58
docs/source/api.rst Normal file
View File

@@ -0,0 +1,58 @@
Code References
===============
Read this page to know how to use primitive-type library.
At present, all methods, type aliases could be imported from path ``primitive_type`` immediately.
Type Aliases
------------
.. automodule:: primitive_type.types
.. note::
Real API path: ``primitive_type.types``
.. currentmodule:: primitive_type.types
.. autotype:: Primitive
.. autotype:: PrimitiveMap
Type Checker
------------
.. automodule:: primitive_type.checker
.. note::
Real API path: ``primitive_type.checker``
.. currentmodule:: primitive_type.checker
.. autofunction:: is_primitive
.. autofunction:: is_nested_dict
Type Converter
--------------
.. automodule:: primitive_type.converter
.. note::
Real API path: ``primitive_type.converter``
.. currentmodule:: primitive_type.converter
.. autoclass:: ConvertError
.. autofunction:: get_primitive_object
.. note::
Methods :data:`get_str_object`, :data:`get_int_object`, :data:`get_float_object` and :data:`get_bool_object` are simplified method for :data:`get_primitive_object`, they return ``get_primitive_object(val, <type>)`` and confirm the return type is specified type.
.. autofunction:: get_str_object
.. autofunction:: get_int_object
.. autofunction:: get_float_object
.. autofunction:: get_bool_object

132
docs/source/conf.py Normal file
View File

@@ -0,0 +1,132 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Import Python modules ---------------------------------------------------
import datetime
import os
import sys
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from sphinx.application import Sphinx
sys.path.insert(0, os.path.abspath(os.path.join("..", "..")))
import primitive_type
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = "primitive-type"
copyright = f"{datetime.datetime.now().year}, CleMooling"
author = "CleMooling"
release = primitive_type.__version__
# -- General configuration ---------------------------------------------------
# https://docs.readthedocs.com/platform/stable/reference/environment-variables.html#envvar-READTHEDOCS
RTD: bool = os.environ.get("READTHEDOCS", "").lower() == "true"
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.autosectionlabel",
"sphinx.ext.intersphinx",
"sphinx.ext.napoleon",
"sphinx.ext.viewcode",
"sphinx_copybutton",
"sphinx_prompt",
"sphinxcontrib.jquery",
"sphinx_inline_tabs",
"sphinxcontrib.mermaid",
"sphinx_design",
"sphinxcontrib.asciinema",
]
source_suffix = [".rst"]
templates_path = ["_templates"]
exclude_patterns = ["build", "Thumbs.db", ".DS_Store"]
note_i18n_text = "Translation links only works in official documentation website, if you're testing locally, they may could not be reached."
rst_prolog = f"""
.. |NOTE_I18N| replace:: {note_i18n_text}
"""
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = "sphinx_rtd_theme"
html_static_path = ["../static"]
html_search_language = "en"
html_css_files = [
# Save the table width
# override wide tables in RTD theme
# https://rackerlabs.github.io/docs-rackspace/tools/rtd-tables.html
"css/theme_overrides.css",
# Tweak styles of the sphinx_inline_tabs extension
"css/codeblock_tab.css",
# Tweak styles of the readthedocs addons
# https://docs.readthedocs.io/en/stable/addons.html
"css/rtd_addon.css",
]
html_js_files = [
("https://cdn.jsdelivr.net/npm/@docsearch/js@3", {"defer": "defer"}),
("js/readthedoc-flyout.js", {"defer": "defer"}),
]
# Show a deeper toctree in the sidebar
# https://stackoverflow.com/questions/27669376/show-entire-toctree-in-read-the-docs-sidebar
html_theme_options = {
"navigation_depth": 6,
"logo_only": True,
}
# html_logo = ''
# -- Options for sphinx-intl -------------------------------------------------
# available languages: en_US, zh_CN
language: str = os.environ.get("READTHEDOCS_LANGUAGE", "en_US")
# po files will be created in this directory
# path is example but recommended.
locale_dirs = ["locales"]
gettext_compact = False # optional
# -- Options for sphinx.ext.autodoc -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html
autodoc_member_order = "bysource"
autodoc_inherit_docstrings = False # so overridden methods won't pop up
add_module_names = False
# -- Options for sphinx.ext.autosectionlabel -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/extensions/autosectionlabel.html
autosectionlabel_prefix_document = True
# -- Options for sphinx.ext.intersphinx -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html
intersphinx_mapping = {
# curl https://docs.python.org/3/objects.inv -o python3-objects.inv
"python": (
"https://docs.python.org/3",
None if RTD else (None, "./python3-objects.inv"),
), # always fetch from internet in rtd env
}
# disable all auto external document references
# implicit ref for general std domain is bad
intersphinx_disabled_reftypes = ["std:*"]
intersphinx_timeout = 30
def autodoc_setup(app: "Sphinx"):
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#event-autodoc-skip-member
def autodoc_skip_member_handler(app_, what, name, obj, skip, options):
return skip
app.connect("autodoc-skip-member", autodoc_skip_member_handler)

80
docs/source/dev.rst Normal file
View File

@@ -0,0 +1,80 @@
Develop
=======
If you would like to participate in the development of this project or create your own fork, you can read this page to learn how to use `uv <https://docs.astral.sh/uv>`__ to manage the development environment.
Download the code
-----------------
The source code is mainly storaged at a self hosted `Gitea <https://about.gitea.com>`__ server `<https://gitfub.cv>`__ .
.. note::
Repo is not in GitHub!
Clone the code to your local develop environment by the command:
.. code-block:: shell
git clone https://gitfub.cv/CleMooling/primitive-type.git
Or if SSH configured fine:
.. code-block:: shell
git clone git@gitfub.cv:CleMooling/primitive-type.git
Sync the uv environment
-----------------------
If you just want to do tests, use:
.. code-block:: shell
uv sync
Then, activate the virtual environment managed by uv:
.. code-block:: shell
source .venv/bin/<activate_script>
.. note::
If you are using `bash <https://www.gnu.org/software/bash>`__ , the script is named ``activate``;
If you are using `fish <https://fishshell.com>`__ , the script is named ``activate.fish``;
If you are using `zsh <https://www.zsh.org>`__ , the script is named ``activate.zsh``.
Now you can do any test you like.
If you want to run the tests built-in, execute:
.. code-block:: shell
python -m unittest discover tests
or:
.. code-block:: shell
uv run python -m unittest discover tests
if outside the uv environment.
If you want to actually participate in the development of this project or fork yourself and develop, you should run:
.. code-block:: shell
uv sync --all-groups
It will sync all needed python packages, including packages that are being used to build the docs.
Then you can edit anything.
Finally
-------
Thanks for reading this documentation! I'll keep updating it to ensure the correctness.

35
docs/source/index.rst Normal file
View File

@@ -0,0 +1,35 @@
.. primitive-type documentation master file, created by
sphinx-quickstart on Tue Feb 10 10:03:15 2026.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
primitive-type documentation
============================
`English <index.html>`__ | `中文(简体) <zh_CN/index.html>`__
.. note::
|NOTE_I18N|
Here is the documentation of primitive-type.
primitive-type is a Python library, you can check a value or object if the type of it is primitive, or convert it to other primitive type.
See the `Code References <api.html>`__ for more details.
.. toctree::
:maxdepth: 2
:caption: Home
Code References<api.rst>
Develop<dev.rst>
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@@ -0,0 +1,242 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2026, CleMooling
# This file is distributed under the same license as the primitive-type
# package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2026.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: primitive-type \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-02-12 13:00+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: zh_CN\n"
"Language-Team: zh_CN <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.18.0\n"
#: ../../source/api.rst:3
msgid "Code References"
msgstr "代码参考"
#: ../../source/api.rst:5
msgid "Read this page to know how to use primitive-type library."
msgstr "阅读此页面以了解如何使用 primitive-type 库。"
#: ../../source/api.rst:7
msgid ""
"At present, all methods, type aliases could be imported from path "
"``primitive_type`` immediately."
msgstr "目前,所有的方法、类型别名都可以从路径 ``primitive_type`` 直接导入。"
#: ../../source/api.rst:10
msgid "Type Aliases"
msgstr "类型别名"
#: of primitive_type.types:1
msgid "Type aliases for primitive types."
msgstr "原始类型的类型别名。"
#: ../../source/api.rst:16
msgid "Real API path: ``primitive_type.types``"
msgstr "实际 API 路径:``primitive_type.types``"
#: of primitive_type.types.Primitive:1
msgid "Type alias for primitive values."
msgstr "原始值的类型别名。"
#: of primitive_type.types.Primitive:3
msgid ""
"Including: :class:`str`, :class:`int`, :class:`float`, :class:`bool`, and"
" :obj:`None`."
msgstr ""
"包括::class:`str`, :class:`int`, :class:`float`, :class:`bool`, and "
":obj:`None`."
#: of primitive_type.types.PrimitiveMap:1
msgid "Type alias for a mapping of string keys to primitive values."
msgstr "字符串键到原始值的映射的类型别名。"
#: of primitive_type.types.PrimitiveMap:3
msgid ""
"This dictionary represents a collection of metadata or attributes where "
"each value is guaranteed to be a :data:`Primitive` type, ensuring type "
"safety and ease of serialization."
msgstr "此字典表示元数据或属性的集合,其中每个值都保证为 :data:`Primitive` 类型,从而确保类型安全并易于序列化。"
#: ../../source/api.rst:24
msgid "Type Checker"
msgstr "类型检查"
#: of primitive_type.checker:1
msgid "Utils for checking objects."
msgstr "检查对象的一些工具。"
#: ../../source/api.rst:30
msgid "Real API path: ``primitive_type.checker``"
msgstr "实际 API 路径:``primitive_type.checker``"
#: of primitive_type.checker.is_primitive:1
msgid "Check an object if it's a primitive object."
msgstr "检查一个对象是不是一个原始对象。"
#: ../../source/api.rst
msgid "Parameters"
msgstr "参数"
#: of primitive_type.checker.is_primitive:3
msgid "Any instance for checking."
msgstr "任何要检查的实例。"
#: ../../source/api.rst
msgid "Returns"
msgstr "返回"
#: of primitive_type.checker.is_primitive:5
msgid "* :obj:`True` -- If the object is primitive * :obj:`False` -- Otherwise."
msgstr "* :obj:`True` -- 如果这个对象是原始的。 * :obj:`False` -- 反之。"
#: of primitive_type.checker.is_primitive:6
msgid ":obj:`True` -- If the object is primitive"
msgstr ":obj:`True` -- 如果这个对象是原始的。"
#: of primitive_type.checker.is_nested_dict:7
#: primitive_type.checker.is_primitive:7
msgid ":obj:`False` -- Otherwise."
msgstr ":obj:`False` -- 反之。"
#: of primitive_type.checker.is_nested_dict:1
msgid "Check a dict if it has nested structures."
msgstr "检查一个字典是否含有嵌套结构。"
#: of primitive_type.checker.is_nested_dict:3
msgid "Any dict object for checking."
msgstr "任何要检查的字典对象。"
#: of primitive_type.checker.is_nested_dict:5
msgid ""
"* :obj:`True` -- If the dict has nested structures. * :obj:`False` -- "
"Otherwise."
msgstr "* :obj:`True` -- 如果这个字典含有嵌套结构。 * :obj:`False` -- 反之。"
#: of primitive_type.checker.is_nested_dict:6
msgid ":obj:`True` -- If the dict has nested structures."
msgstr ":obj:`True` -- 如果这个字典含有嵌套结构。"
#: ../../source/api.rst:38
msgid "Type Converter"
msgstr "类型转换"
#: of primitive_type.converter:1
msgid "A quick and simple converter to convert the type of an object."
msgstr "一个快速简单的类型转换器,可用于转换单个对象的类型。"
#: ../../source/api.rst:44
msgid "Real API path: ``primitive_type.converter``"
msgstr "实际 API 路径:``primitive_type.converter``"
#: of primitive_type.converter.ConvertError:1
msgid "An exception should happens when conversion failed."
msgstr "一个应在类型转换失败时被抛出的错误。"
#: of primitive_type.converter.get_primitive_object:1
msgid "Get a primitive object from a given value."
msgstr "从给定的一个值中获取一个原始对象。"
#: of primitive_type.converter.get_bool_object:3
#: primitive_type.converter.get_float_object:3
#: primitive_type.converter.get_int_object:3
#: primitive_type.converter.get_primitive_object:3
#: primitive_type.converter.get_str_object:3
msgid "The given value wants to be converted."
msgstr "需要被转换(类型)的给定对象。"
#: of primitive_type.converter.get_primitive_object:4
msgid ""
"The target type of object that finally converted out. Default to "
":obj:`None` as disabled."
msgstr "对象最终要转换出的目标类型。默认为 :obj:`None` 以禁用(即自动推断)。"
#: of primitive_type.converter.get_primitive_object:6
msgid ""
"* :class:`str` -- If given value is a normal string, or convert to if "
"type specified. * :class:`int` -- The origin object or convert to. * "
":class:`float` -- The origin object or convert to. * :class:`bool` -- The"
" origin object or convert to. * :obj:`None` -- Only when given value is "
":obj:`None`."
msgstr ""
"* :class:`str` -- 如果给定的值是一个普通字符串,或者指定了转换类型。 * :class:`int` -- 原始的或转换出的对象。"
" * :class:`float` -- 原始的或转换出的对象。 * :class:`bool` -- 原始的或转换出的对象。 * "
":obj:`None` -- 仅在给定的对象为 :obj:`None` 时。"
#: of primitive_type.converter.get_primitive_object:7
msgid ""
":class:`str` -- If given value is a normal string, or convert to if type "
"specified."
msgstr ":class:`str` -- 如果给定的值是一个普通字符串,或者指定了转换类型。"
#: of primitive_type.converter.get_primitive_object:8
msgid ":class:`int` -- The origin object or convert to."
msgstr ":class:`int` -- 原始的或转换出的对象。"
#: of primitive_type.converter.get_primitive_object:9
msgid ":class:`float` -- The origin object or convert to."
msgstr ":class:`float` -- 原始的或转换出的对象。"
#: of primitive_type.converter.get_primitive_object:10
msgid ":class:`bool` -- The origin object or convert to."
msgstr ":class:`bool` -- 原始的或转换出的对象。"
#: of primitive_type.converter.get_primitive_object:11
msgid ":obj:`None` -- Only when given value is :obj:`None`."
msgstr ":obj:`None` -- 仅在给定的对象为 :obj:`None` 时。"
#: ../../source/api.rst:53
msgid ""
"Methods :data:`get_str_object`, :data:`get_int_object`, "
":data:`get_float_object` and :data:`get_bool_object` are simplified "
"method for :data:`get_primitive_object`, they return "
"``get_primitive_object(val, <type>)`` and confirm the return type is "
"specified type."
msgstr "方法 :data:`get_str_object`、:data:`get_int_object`、:data:`get_float_object` 和 :data:`get_bool_object` 是 :data:`get_primitive_object` 的简化方法,他们会返回 ``get_primitive_object(val, <type>)`` 并确认返回类型是指定的类型。"
#: of primitive_type.converter.get_str_object:1
msgid "Get a string object from a given value."
msgstr "从给定的一个值中获取一个原始对象。"
#: of primitive_type.converter.get_str_object:5
msgid "A string object."
msgstr "一个字符串对象。"
#: of primitive_type.converter.get_int_object:1
msgid "Get an integer object from a given value."
msgstr "从给定的一个值中获取一个整数对象。"
#: of primitive_type.converter.get_int_object:5
msgid "An integer object."
msgstr "一个整数对象。"
#: of primitive_type.converter.get_float_object:1
msgid "Get a float object from a given value."
msgstr "从给定的一个值中获取一个浮点数对象。"
#: of primitive_type.converter.get_float_object:5
msgid "A float object."
msgstr "一个浮点数对象。"
#: of primitive_type.converter.get_bool_object:1
msgid "Get a boolean object from a given value."
msgstr "从给定的一个值中获取一个布尔值对象。"
#: of primitive_type.converter.get_bool_object:5
msgid "A bool object."
msgstr "一个布尔值对象。"
#~ msgid "Entrypoint of this package."
#~ msgstr ""

View File

@@ -0,0 +1,127 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2026, CleMooling
# This file is distributed under the same license as the primitive-type
# package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2026.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: primitive-type \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-02-10 12:30+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: zh_CN\n"
"Language-Team: zh_CN <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.18.0\n"
#: ../../source/dev.rst:3
msgid "Develop"
msgstr "开发"
#: ../../source/dev.rst:5
msgid ""
"If you would like to participate in the development of this project or "
"create your own fork, you can read this page to learn how to use `uv "
"<https://docs.astral.sh/uv>`__ to manage the development environment."
msgstr "如果你想要参与这个项目的开发,或是创建你自己的分支,你可以阅读此页以学习如何使用 `uv <https://docs.astral.sh/uv>`__ 来管理开发环境。"
#: ../../source/dev.rst:8
msgid "Download the code"
msgstr "下载代码"
#: ../../source/dev.rst:10
msgid ""
"The source code is mainly storaged at a self hosted `Gitea "
"<https://about.gitea.com>`__ server `<https://gitfub.cv>`__ ."
msgstr "源代码主要存储在一个自建的 `Gitea <https://about.gitea.com>`__ 服务器 `<https://gitfub.cv>`__ 。"
#: ../../source/dev.rst:14
msgid "Repo is not in GitHub!"
msgstr "(源码)仓库不在 GitHub"
#: ../../source/dev.rst:16
msgid "Clone the code to your local develop environment by the command:"
msgstr "使用这个命令,复制代码到你的本地开发环境中:"
#: ../../source/dev.rst:22
msgid "Or if SSH configured fine:"
msgstr "或者用 SSH 如果已配置好:"
#: ../../source/dev.rst:29
msgid "Sync the uv environment"
msgstr "同步 uv 环境"
#: ../../source/dev.rst:31
msgid "If you just want to do tests, use:"
msgstr "如果你只是想进行测试,使用:"
#: ../../source/dev.rst:37
msgid "Then, activate the virtual environment managed by uv:"
msgstr "然后,激活 uv 管理的虚拟环境:"
#: ../../source/dev.rst:45
msgid ""
"If you are using `bash <https://www.gnu.org/software/bash>`__ , the "
"script is named ``activate``;"
msgstr "如果你使用 `bash <https://www.gnu.org/software/bash>`__ 则脚本activate_script名为 ``activate``。"
#: ../../source/dev.rst:47
msgid ""
"If you are using `fish <https://fishshell.com>`__ , the script is named "
"``activate.fish``;"
msgstr "如果你使用 `fish <https://fishshell.com>`__ 则脚本activate_script名为 ``activate.fish``。"
#: ../../source/dev.rst:49
msgid ""
"If you are using `zsh <https://www.zsh.org>`__ , the script is named "
"``activate.zsh``."
msgstr "如果你使用 `zsh <https://www.zsh.org>`__ 则脚本activate_script名为 ``activate.zsh``。"
#: ../../source/dev.rst:51
msgid "Now you can do any test you like."
msgstr "现在你可以执行任何你想要的测试了。"
#: ../../source/dev.rst:53
msgid "If you want to run the tests built-in, execute:"
msgstr "如果你想运行内置的测试,执行:"
#: ../../source/dev.rst:59
msgid "or:"
msgstr "或者:"
#: ../../source/dev.rst:65
msgid "if outside the uv environment."
msgstr "如果在 uv 环境之外。"
#: ../../source/dev.rst:67
msgid ""
"If you want to actually participate in the development of this project or"
" fork yourself and develop, you should run:"
msgstr "如果你想实际参与这个项目的开发或自行分支,你应该运行:"
#: ../../source/dev.rst:73
msgid ""
"It will sync all needed python packages, including packages that are "
"being used to build the docs."
msgstr "这将同步所有 Python 包,包括构建文档要用到的包。"
#: ../../source/dev.rst:75
msgid "Then you can edit anything."
msgstr "然后你可以开始随意编辑(代码)。"
#: ../../source/dev.rst:78
msgid "Finally"
msgstr "结语"
#: ../../source/dev.rst:80
msgid ""
"Thanks for reading this documentation! I'll keep updating it to ensure "
"the correctness."
msgstr "感谢阅读这些文档!我会持续更新以确保准确性。"

View File

@@ -0,0 +1,96 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) 2026, CleMooling
# This file is distributed under the same license as the primitive-type
# package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2026.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: primitive-type \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-02-12 14:19+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: zh_CN\n"
"Language-Team: zh_CN <LL@li.org>\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.18.0\n"
#: ../../source/index.rst:22
msgid "Code References"
msgstr "代码参考"
#: ../../source/index.rst:22
msgid "Develop"
msgstr "开发"
#: ../../source/index.rst:22
msgid "Home"
msgstr "主页"
#: ../../source/index.rst:7
msgid "primitive-type documentation"
msgstr "primitive-type 文档"
#: ../../source/index.rst:9
msgid "`English <index.html>`__ | `中文(简体) <zh_CN/index.html>`__"
msgstr "`English <../index.html>`__ | `中文(简体) <index.html>`__"
#: ../../source/index.rst:13
msgid "|NOTE_I18N|"
msgstr "翻译链接仅在官方文档网站有效;若在本地测试,可能无法访问。"
#: ../../source/index.rst:15
msgid "Here is the documentation of primitive-type."
msgstr "这里是 primitive-type 的文档。"
#: ../../source/index.rst:17
msgid ""
"primitive-type is a Python library, you can check a value or object if "
"the type of it is primitive, or convert it to other primitive type."
msgstr "primitive-type 是一个 Python 库,你可以用来检查一个值或者对象是不是原始类型,或将其转换为其他原始类型。"
#: ../../source/index.rst:19
msgid "See the `Code References <api.html>`__ for more details."
msgstr "查看 `代码参考 <api.html>`__ 以获取更多详情。"
#: ../../source/index.rst:30
msgid "Indices and tables"
msgstr "目录和索引"
#: ../../source/index.rst:32
msgid ":ref:`genindex`"
msgstr ""
#: ../../source/index.rst:33
msgid ":ref:`modindex`"
msgstr ""
#: ../../source/index.rst:34
msgid ":ref:`search`"
msgstr ""
#~ msgid "Contents:"
#~ msgstr ""
#~ msgid ""
#~ "Add your content using ``reStructuredText``"
#~ " syntax. See the `reStructuredText "
#~ "<https://www.sphinx-"
#~ "doc.org/en/master/usage/restructuredtext/index.html>`_ "
#~ "documentation for details."
#~ msgstr ""
#~ msgid "`English <index.rst>`__ | `中文(简体) <zh_CN/index.html>`__ @@NOTE_I18N@@"
#~ msgstr ""
#~ msgid "@@NOTE_I18N@@"
#~ msgstr ""
#~ msgid "`English <index.rst>`__ | `中文(简体) <zh_CN/index.html>`__"
#~ msgstr ""

17
docs/static/css/codeblock_tab.css vendored Normal file
View File

@@ -0,0 +1,17 @@
/* tweak tab size */
:root {
--tabs--padding-x: 1em;
}
.tab-set > label {
padding: 0.3em var(--tabs--padding-x) 0.3em;
}
/* remove duplicated border line */
.tab-content {
box-shadow: none;
}
/* make the tab text unselectable */
.tab-label {
user-select: none;
}

4
docs/static/css/rtd_addon.css vendored Normal file
View File

@@ -0,0 +1,4 @@
/* Remove the ugly switch menu */
.wy-side-nav-search > div.switch-menus {
display: none;
}

65
docs/static/css/theme_overrides.css vendored Normal file
View File

@@ -0,0 +1,65 @@
/* override table width restrictions */
@media screen and (min-width: 767px) {
.wy-table-responsive table td,
.wy-table-responsive table th {
/* !important prevents the common CSS stylesheets from overriding
this as on RTD they are loaded after this stylesheet */
white-space: normal !important;
}
.wy-table-responsive {
margin-bottom: 24px;
max-width: 100%;
overflow: visible !important;
}
}
/* +50px width for the main doc container nav */
.wy-nav-content {
max-width: 850px !important;
}
/* prevent keyword in codeblock in docstring from being italic */
html.writer-html4 .rst-content dl:not(.docutils) .k,
html.writer-html5
.rst-content
dl[class]:not(.option-list):not(.field-list):not(.footnote):not(
.glossary
):not(.simple)
.k {
font-style: inherit !important;
}
/* ofc */
.highlight {
tab-size: 4;
}
/* remove the bottom margin for tabs from sphinx_inline_tabs */
.tab-set {
margin: 0;
}
/* better inline codeblocks */
.rst-content code,
.rst-content tt,
code {
background: rgba(
251,
251,
251
); /* don't use pure white, that's too shiny */
}
/*
render multi-line cell of tables correctly
https://github.com/readthedocs/sphinx_rtd_theme/issues/1241
*/
.rst-content table.docutils td:first-child,
.rst-content table.docutils th:first-child,
.rst-content table.field-list td:first-child,
.rst-content table.field-list th:first-child,
.wy-table td:first-child,
.wy-table th:first-child {
border-left-width: 1px;
}

19
docs/static/js/readthedoc-flyout.js vendored Normal file
View File

@@ -0,0 +1,19 @@
function waitForElement(selector, callback) {
if (document.querySelector(selector)) {
callback();
} else {
setTimeout(function () {
waitForElement(selector, callback);
}, 100);
}
}
window.addEventListener("load", () => {
waitForElement("readthedocs-flyout", () => {
let flyout = document.querySelector("readthedocs-flyout").shadowRoot;
let target = flyout.querySelector("header");
target.addEventListener("click", (e) => {
e.stopPropagation();
});
});
});

4
docs/update_i18n.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
make gettext
echo "Currently support zh_CN only."
sphinx-intl update -p build/gettext -l zh_CN

7
docs/upload Normal file
View File

@@ -0,0 +1,7 @@
Change content of this file and submit commits to trigger ci.
+2026-02-10 17:15
+2026-02-10 17:34
+2026-02-10 20:00
+2026-02-10 20:40
+2026-02-10 21:17
+2026-02-10 21:32

View File

@@ -1,6 +1,6 @@
[project]
name = "primitive-type"
version = "0.1.0"
version = "0.1.2"
description = "Check a value or object if the type of it is primitive, or convert it to other primitive type in Python."
readme = "README.md"
license = { file = "LICENSE" }
@@ -9,6 +9,7 @@ keywords = ["type-checking", "primitive", "conversion"]
classifiers = [
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Typing :: Typed",
]
requires-python = ">=3.12"
@@ -16,9 +17,30 @@ dependencies = ["beartype>=0.22.9"]
[project.urls]
Homepage = "https://gitfub.cv/CleMooling/primitive-type"
Documentation = "https://docs.staringplanet.top/primitive-type"
Repository = "https://gitfub.cv/CleMooling/primitive-type.git"
Issues = "https://gitfub.cv/CleMooling/primitive-type/issues"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[dependency-groups]
dev = ["ruff>=0.15.0", "ty>=0.0.15"]
docs = [
"jieba>=0.42.1",
"sphinx>=9.0",
"sphinx-autobuild>=2025.8.25",
"sphinx-autodoc-typehints>=3.6.1",
"sphinx-copybutton>=0.5.2",
"sphinx-design>=0.7.0",
"sphinx-inline-tabs>=2025.12.21.14",
"sphinx-intl>=2.3.2",
"sphinx-prompt>=1.10.2",
"sphinx-rtd-theme>=3.0.0rc1",
"sphinxcontrib-asciinema>=0.4.3",
"sphinxcontrib-mermaid>=2.0.0",
]
[tool.ruff]
line-length = 79

View File

@@ -2,7 +2,14 @@
from primitive_type.types import Primitive, PrimitiveMap
from primitive_type.checker import is_primitive, is_nested_dict
from primitive_type.converter import get_primitive_object, ConvertError
from primitive_type.converter import (
get_primitive_object,
get_str_object,
get_int_object,
get_float_object,
get_bool_object,
ConvertError,
)
from importlib.metadata import version, PackageNotFoundError
try:
@@ -17,5 +24,9 @@ __all__ = [
"is_primitive",
"is_nested_dict",
"get_primitive_object",
"get_str_object",
"get_int_object",
"get_float_object",
"get_bool_object",
"ConvertError",
]

View File

@@ -13,7 +13,9 @@ class ConvertError(TypeError):
@beartype
def get_primitive_object(val: Primitive, obj_type: type[Primitive] = None) -> Primitive:
def get_primitive_object(
val: Primitive, obj_type: type[Primitive] = None
) -> Primitive:
"""Get a primitive object from a given value.
:param val: The given value wants to be converted.
@@ -30,7 +32,9 @@ def get_primitive_object(val: Primitive, obj_type: type[Primitive] = None) -> Pr
if val is None:
if obj_type_required:
raise TypeError("Given value is None, could not convert to other type!")
raise TypeError(
"Given value is None, could not convert to other type!"
)
return None
if not obj_type_required:
@@ -72,3 +76,43 @@ def get_primitive_object(val: Primitive, obj_type: type[Primitive] = None) -> Pr
raise ConvertError(f"Could not convert '{val}' to type '{obj_type}'.")
return val
def get_str_object(val: Primitive) -> str:
"""Get a string object from a given value.
:param val: The given value wants to be converted.
:return: A string object.
"""
return get_primitive_object(val, str) # ty: ignore[invalid-return-type]
def get_int_object(val: Primitive) -> int:
"""Get an integer object from a given value.
:param val: The given value wants to be converted.
:return: An integer object.
"""
return get_primitive_object(val, int) # ty: ignore[invalid-return-type]
def get_float_object(val: Primitive) -> float:
"""Get a float object from a given value.
:param val: The given value wants to be converted.
:return: A float object.
"""
return get_primitive_object(val, float) # ty: ignore[invalid-return-type]
def get_bool_object(val: Primitive) -> bool:
"""Get a boolean object from a given value.
:param val: The given value wants to be converted.
:return: A bool object.
"""
return get_primitive_object(val, bool) # ty: ignore[invalid-return-type]

View File

@@ -1,6 +1,13 @@
import unittest
from primitive_type.converter import get_primitive_object, ConvertError
from primitive_type.converter import (
get_primitive_object,
get_str_object,
get_int_object,
get_float_object,
get_bool_object,
ConvertError,
)
class TestPrimitiveTypeConverter(unittest.TestCase):
@@ -61,6 +68,35 @@ class TestPrimitiveTypeConverter(unittest.TestCase):
with self.assertRaises(ConvertError):
get_primitive_object("abc", obj_type=float)
def test_simplified_methods(self):
"""Test simplified methods for `get_primitive_object`"""
# Test `get_str_object`
self.assertEqual(get_str_object(1), "1")
self.assertEqual(get_str_object(1.232), "1.232")
self.assertEqual(get_str_object(True), "True")
# Test `get_int_object`
self.assertEqual(get_int_object("233"), 233)
self.assertEqual(get_int_object(1.847), 1)
self.assertEqual(get_int_object(True), 1)
self.assertEqual(get_int_object(False), 0)
with self.assertRaises(ConvertError):
get_int_object("string")
# Test `get_float_object`
self.assertEqual(get_float_object(1), 1.0)
self.assertEqual(get_float_object("1.414"), 1.414)
self.assertEqual(get_float_object(True), 1.0)
with self.assertRaises(ConvertError):
get_float_object("string")
# Test `get_bool_object`
self.assertEqual(get_bool_object(1), True)
self.assertEqual(get_bool_object(0), False)
self.assertEqual(get_bool_object(-3.147), False)
self.assertEqual(get_bool_object("true"), True)
self.assertEqual(get_bool_object("True"), True)
self.assertEqual(get_bool_object("false"), False)
self.assertEqual(get_bool_object("False"), False)
self.assertEqual(get_bool_object("string"), False)
if __name__ == "__main__":
unittest.main()