This is an automated email from the ASF dual-hosted git repository.
hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-pycasbin.git
The following commit(s) were added to refs/heads/master by this push:
new 52c03ab docs: fix typos and Go-specific inaccuracies in README and
docstrings
52c03ab is described below
commit 52c03ab5ed30e219cd8e123e8afb1bf5bd8b190b
Author: Yang Luo <[email protected]>
AuthorDate: Wed Sep 23 14:08:24 2026 +0800
docs: fix typos and Go-specific inaccuracies in README and docstrings
---
README.md | 46 ++++++++++++++++++++--------------------
casbin/util/builtin_operators.py | 2 +-
casbin/util/expression.py | 2 +-
casbin/util/util.py | 2 +-
tests/test_enforcer.py | 4 ++--
5 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/README.md b/README.md
index 9184df8..16d392c 100644
--- a/README.md
+++ b/README.md
@@ -54,14 +54,14 @@ Casbin is a powerful and efficient open-source access
control library for Python
1. [**ACL (Access Control
List)**](https://en.wikipedia.org/wiki/Access_control_list)
2. **ACL with [superuser](https://en.wikipedia.org/wiki/Superuser)**
3. **ACL without users**: especially useful for systems that don't have
authentication or user log-ins.
-3. **ACL without resources**: some scenarios may target for a type of
resources instead of an individual resource by using permissions like
``write-article``, ``read-log``. It doesn't control the access to a specific
article or log.
-4. **[RBAC (Role-Based Access
Control)](https://en.wikipedia.org/wiki/Role-based_access_control)**
-5. **RBAC with resource roles**: both users and resources can have roles (or
groups) at the same time.
-6. **RBAC with domains/tenants**: users can have different role sets for
different domains/tenants.
-7. **[ABAC (Attribute-Based Access
Control)](https://en.wikipedia.org/wiki/Attribute-Based_Access_Control)**:
syntax sugar like ``resource.Owner`` can be used to get the attribute for a
resource.
-8.
**[RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer)**:
supports paths like ``/res/*``, ``/res/:id`` and HTTP methods like ``GET``,
``POST``, ``PUT``, ``DELETE``.
-9. **Deny-override**: both allow and deny authorizations are supported, deny
overrides the allow.
-10. **Priority**: the policy rules can be prioritized like firewall rules.
+4. **ACL without resources**: some scenarios may target for a type of
resources instead of an individual resource by using permissions like
``write-article``, ``read-log``. It doesn't control the access to a specific
article or log.
+5. **[RBAC (Role-Based Access
Control)](https://en.wikipedia.org/wiki/Role-based_access_control)**
+6. **RBAC with resource roles**: both users and resources can have roles (or
groups) at the same time.
+7. **RBAC with domains/tenants**: users can have different role sets for
different domains/tenants.
+8. **[ABAC (Attribute-Based Access
Control)](https://en.wikipedia.org/wiki/Attribute-Based_Access_Control)**:
syntax sugar like ``resource.Owner`` can be used to get the attribute for a
resource.
+9.
**[RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer)**:
supports paths like ``/res/*``, ``/res/:id`` and HTTP methods like ``GET``,
``POST``, ``PUT``, ``DELETE``.
+10. **Deny-override**: both allow and deny authorizations are supported, deny
overrides the allow.
+11. **Priority**: the policy rules can be prioritized like firewall rules.
## How it works?
@@ -100,16 +100,16 @@ It means:
- alice can read data1
- bob can write data2
-We also support multi-line mode by appending '\\' in the end:
+We also support multi-line mode by appending '\\' at the end:
```ini
# Matchers
[matchers]
-m = r.sub == p.sub && r.obj == p.obj \
+m = r.sub == p.sub && r.obj == p.obj \
&& r.act == p.act
```
-Further more, if you are using ABAC, you can try operator `in` like following
in Casbin **golang** edition (jCasbin and Node-Casbin are not supported yet):
+Furthermore, if you are using ABAC, you can use the `in` operator like the
following:
```ini
# Matchers
@@ -117,9 +117,9 @@ Further more, if you are using ABAC, you can try operator
`in` like following i
m = r.obj == p.obj && r.act == p.act || r.obj in ('data2', 'data3')
```
-But you **SHOULD** make sure that the length of the array is **MORE** than
**1**, otherwise there will cause it to panic.
+Note: the right-hand side is a normal Python tuple, so a single-element one
**MUST** keep its trailing comma, e.g. ``('data2',)``. Writing ``('data2')``
makes it a plain string, and ``in`` then silently degrades to a substring match
(``data`` would match ``data2``).
-For more operators, you may take a look at
[govaluate](https://github.com/Knetic/govaluate)
+For more operators, you may take a look at
[simpleeval](https://github.com/danthedeckie/simpleeval), the expression engine
used by pycasbin.
## Features
@@ -128,7 +128,7 @@ What Casbin does:
1. enforce the policy in the classic ``{subject, object, action}`` form or a
customized form as you defined, both allow and deny authorizations are
supported.
2. handle the storage of the access control model and its policy.
3. manage the role-user mappings and role-role mappings (aka role hierarchy in
RBAC).
-4. support built-in superuser like ``root`` or ``administrator``. A superuser
can do anything without explict permissions.
+4. support built-in superuser like ``root`` or ``administrator``. A superuser
can do anything without explicit permissions.
5. multiple built-in operators to support the rule matching. For example,
``keyMatch`` can map a resource key ``/foo/bar`` to the pattern ``/foo*``.
What Casbin does NOT do:
@@ -180,7 +180,7 @@ else:
pass
```
-3. Besides the static policy file, Casbin also provides API for permission
management at run-time. For example, You can get all the roles assigned to a
user as below:
+3. Besides the static policy file, Casbin also provides API for permission
management at run-time. For example, you can get all the roles assigned to a
user as below:
```python
roles = e.get_roles_for_user("alice")
@@ -213,7 +213,7 @@ https://casbin.org/docs/role-managers
## Async Enforcer
-If your code use `async` / `await` and is heavily dependent on I/O operations,
you can adopt Async Enforcer!
+If your code uses `async` / `await` and is heavily dependent on I/O
operations, you can adopt Async Enforcer!
1. Create an async engine and new a Casbin AsyncEnforcer with a model file and
an async Pycasbin adapter (AsyncAdapter subclass):
@@ -276,22 +276,22 @@ https://casbin.org/docs/benchmark
## Logging
-pycasbin leverages the default Python logging mechanism. The pycasbin package
makes a call to `logging.getLogger()` to set the logger. No special logging
configuration is needed other than initializing the logger in the parent
application. If no logging is initialized within the parent application, you
will not see any log messages from pycasbin. At the same time, When you enable
log in pycasbin, you can specify the logging configuration through the
parameter `logging_config`. If no conf [...]
+pycasbin leverages the default Python logging mechanism. The pycasbin package
makes a call to `logging.getLogger()` to set the logger. No special logging
configuration is needed other than initializing the logger in the parent
application. If no logging is initialized within the parent application, you
will not see any log messages from pycasbin. At the same time, when you enable
log in pycasbin, you can specify the logging configuration through the
parameter `logging_config`. If no conf [...]
## Examples
| Model | Model file
| Policy file
|
|---------------------------|----------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------|
| ACL |
[basic_model.conf](https://github.com/casbin/casbin/blob/master/examples/basic_model.conf)
|
[basic_policy.csv](https://github.com/casbin/casbin/blob/master/examples/basic_policy.csv)
|
-| ACL with superuser |
[basic_model_with_root.conf](https://github.com/casbin/casbin/blob/master/examples/basic_with_root_model.conf)
|
[basic_policy.csv](https://github.com/casbin/casbin/blob/master/examples/basic_policy.csv)
|
-| ACL without users |
[basic_model_without_users.conf](https://github.com/casbin/casbin/blob/master/examples/basic_without_users_model.conf)
|
[basic_policy_without_users.csv](https://github.com/casbin/casbin/blob/master/examples/basic_without_users_policy.csv)
|
-| ACL without resources |
[basic_model_without_resources.conf](https://github.com/casbin/casbin/blob/master/examples/basic_without_resources_model.conf)
|
[basic_policy_without_resources.csv](https://github.com/casbin/casbin/blob/master/examples/basic_without_resources_policy.csv)
|
+| ACL with superuser |
[basic_with_root_model.conf](https://github.com/casbin/casbin/blob/master/examples/basic_with_root_model.conf)
|
[basic_policy.csv](https://github.com/casbin/casbin/blob/master/examples/basic_policy.csv)
|
+| ACL without users |
[basic_without_users_model.conf](https://github.com/casbin/casbin/blob/master/examples/basic_without_users_model.conf)
|
[basic_without_users_policy.csv](https://github.com/casbin/casbin/blob/master/examples/basic_without_users_policy.csv)
|
+| ACL without resources |
[basic_without_resources_model.conf](https://github.com/casbin/casbin/blob/master/examples/basic_without_resources_model.conf)
|
[basic_without_resources_policy.csv](https://github.com/casbin/casbin/blob/master/examples/basic_without_resources_policy.csv)
|
| RBAC |
[rbac_model.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_model.conf)
|
[rbac_policy.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_policy.csv)
|
-| RBAC with resource roles |
[rbac_model_with_resource_roles.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_resource_roles_model.conf)
|
[rbac_policy_with_resource_roles.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_resource_roles_policy.csv)
|
-| RBAC with domains/tenants |
[rbac_model_with_domains.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_domains_model.conf)
|
[rbac_policy_with_domains.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_domains_policy.csv)
|
+| RBAC with resource roles |
[rbac_with_resource_roles_model.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_resource_roles_model.conf)
|
[rbac_with_resource_roles_policy.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_resource_roles_policy.csv)
|
+| RBAC with domains/tenants |
[rbac_with_domains_model.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_domains_model.conf)
|
[rbac_with_domains_policy.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_domains_policy.csv)
|
| ABAC |
[abac_model.conf](https://github.com/casbin/casbin/blob/master/examples/abac_model.conf)
| N/A
|
| RESTful |
[keymatch_model.conf](https://github.com/casbin/casbin/blob/master/examples/keymatch_model.conf)
|
[keymatch_policy.csv](https://github.com/casbin/casbin/blob/master/examples/keymatch_policy.csv)
|
-| Deny-override |
[rbac_model_with_deny.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_deny_model.conf)
|
[rbac_policy_with_deny.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_deny_policy.csv)
|
+| Deny-override |
[rbac_with_deny_model.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_deny_model.conf)
|
[rbac_with_deny_policy.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_deny_policy.csv)
|
| Priority |
[priority_model.conf](https://github.com/casbin/casbin/blob/master/examples/priority_model.conf)
|
[priority_policy.csv](https://github.com/casbin/casbin/blob/master/examples/priority_policy.csv)
|
## Middlewares
diff --git a/casbin/util/builtin_operators.py b/casbin/util/builtin_operators.py
index 62e0f02..2aff2ad 100644
--- a/casbin/util/builtin_operators.py
+++ b/casbin/util/builtin_operators.py
@@ -107,7 +107,7 @@ def key_get2(key1, key2, path_var):
def key_match3(key1, key2):
- """determines determines whether key1 matches the pattern of key2 (similar
to RESTful path), key2 can contain a *.
+ """determines whether key1 matches the pattern of key2 (similar to RESTful
path), key2 can contain a *.
For example, "/foo/bar" matches "/foo/*", "/resource1" matches
"/{resource}"
"""
diff --git a/casbin/util/expression.py b/casbin/util/expression.py
index 3be2015..e2abb5d 100644
--- a/casbin/util/expression.py
+++ b/casbin/util/expression.py
@@ -34,7 +34,7 @@ class SimpleEval(EvalWithCompoundTypes):
self.ast_parsed_value = ast.parse(expr.strip()).body[0].value
def eval(self, names=None):
- """evaluate an expresssion, using the operators, functions and
+ """evaluate an expression, using the operators, functions and
names previously set up."""
if names:
diff --git a/casbin/util/util.py b/casbin/util/util.py
index 1e13890..618f124 100644
--- a/casbin/util/util.py
+++ b/casbin/util/util.py
@@ -84,7 +84,7 @@ def has_eval(s):
def replace_eval(expr, rules):
- """replace all occurences of function eval with rules"""
+ """replace all occurrences of function eval with rules"""
pos = 0
match = eval_reg.search(expr, pos)
while match:
diff --git a/tests/test_enforcer.py b/tests/test_enforcer.py
index a4c5672..64f9e2f 100644
--- a/tests/test_enforcer.py
+++ b/tests/test_enforcer.py
@@ -287,7 +287,7 @@ class TestConfig(TestCaseBase):
self.assertTrue(e.enforce("bob", "data2", "write"))
self.assertTrue(e.enforce("alice", "data2", "read"))
self.assertTrue(e.enforce("alice", "data2", "write"))
- self.assertFalse(e.enforce("bogus", "data2", "write")) # test
non-existant subject
+ self.assertFalse(e.enforce("bogus", "data2", "write")) # test
non-existent subject
def test_enforce_rbac_empty_policy(self):
e = self.get_enforcer(get_examples("rbac_model.conf"),
get_examples("empty_policy.csv"))
@@ -883,7 +883,7 @@ class TestConfigAsync(IsolatedAsyncioTestCase):
self.assertTrue(e.enforce("bob", "data2", "write"))
self.assertTrue(e.enforce("alice", "data2", "read"))
self.assertTrue(e.enforce("alice", "data2", "write"))
- self.assertFalse(e.enforce("bogus", "data2", "write")) # test
non-existant subject
+ self.assertFalse(e.enforce("bogus", "data2", "write")) # test
non-existent subject
async def test_enforce_rbac_empty_policy(self):
e = self.get_enforcer(get_examples("rbac_model.conf"),
get_examples("empty_policy.csv"))
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]