Tecnativa / doodba-copier-template

A Copier template for Doodba projects
Boost Software License 1.0
86 stars 114 forks source link

builtins.KeyError KeyError: 'ir.http' #42

Closed carlosecv closed 4 years ago

carlosecv commented 4 years ago

Template used: Odoo 13 PostgreSQL 12

Trying http://localhost:13069/ :100:

builtins.KeyError KeyError: 'ir.http'

Traceback (most recent call last) File "/opt/odoo/custom/src/odoo/odoo/service/wsgi_server.py", line 142, in application return application_unproxied(environ, start_response) File "/opt/odoo/custom/src/odoo/odoo/service/wsgi_server.py", line 117, in application_unproxied result = odoo.http.root(environ, start_response) File "/opt/odoo/custom/src/odoo/odoo/http.py", line 1287, in call return self.dispatch(environ, start_response) File "/opt/odoo/custom/src/odoo/odoo/http.py", line 1257, in call return self.app(environ, start_wrapped) File "/usr/local/lib/python3.7/site-packages/werkzeug/wsgi.py", line 766, in call return self.app(environ, start_response) File "/opt/odoo/custom/src/odoo/odoo/http.py", line 1441, in dispatch ir_http = request.registry['ir.http'] File "/opt/odoo/custom/src/odoo/odoo/modules/registry.py", line 177, in getitem Open an interactive python shell in this framereturn self.models[model_name] KeyError: 'ir.http'


I create a new copier instance, this are the parameters:

Tell me who you are. If private modules do not include this author, pylint will warn you.

projectauthor? Format: str 🎀 [RealSystems]: What's your project name? Do not use dots or spaces in the name; just "A-Za-z0-9-" please.

project_name? Format: str 🎀 [proyecto13]: It's important to use a good license for your project. In https://choosealicense.com/ you can read details about most common FOSS ones. In https://www.odoo.com/documentation/user/13.0/legal/licenses/licenses.html you can find other propietary licenses we support in this scaffolding. Make a wise choice! So, what's your project's license?

project_license? Format: yaml 🎀 (1) No license (2) Apache License 2.0 (3) Boost Software License 1.0 (4) GNU Affero General Public License (AGPL) 3.0 or later (5) GNU Library or "Lesser" General Public License (LGPL) 3.0 or later (6) MIT license (7) Odoo Enterprise Edition License v1.0 (8) Odoo Proprietary License v1.0 Choice [4]: If you host this project in Gitlab, then please enter here the project URL. It must have no trailing slash. πŸ’‘ If you don't use Gitlab, leave this empty and ignore all other Gitlab questions. Example: https://gitlab.com/Tecnativa/your-doodba-project.

gitlab_url? Format: str 🎀 [None]: Write the main production domain for this project. Only the domain, no protocol or things like that. Example: www.example.com

domain_prod? Format: str 🎀 [None]: Write a list of alternative domains that should produce a 301 redirection to the main domain. Example: [example.com, www.example.org, example.org]

domain_prod_alternatives? Format: yaml 🎀 [None]: Write the test domain for this project. Only the domain, no protocol or things like that. Example: demo.example.com

domain_test? Format: str 🎀 [None]: Tell me the list of paths which where you want to forbid crawlers. Imagine you do not want your /shop and /shop/** pages to be indexed. Then put here [/shop]. ⚠️ It must be a list. And this is only supported if you deploy with Traefik. πŸ’‘ We will convert this to Path rules. Check valid syntax in https://docs.traefik.io/routing/routers/#rule

paths_without_crawlers? Format: yaml 🎀 [['/web', '/website/info']]: If you need to whitelist certain CIDR to allow only them to access your Odoo instance, set that here please. ⚠️ It must be a list. And this is only supported if you deploy with Traefik 2+.

cidr_whitelist? Format: yaml 🎀 [None]: On which odoo version is it based?

odoo_version? Format: float 🎀 (1) 7.0 (2) 8.0 (3) 9.0 (4) 10.0 (5) 11.0 (6) 12.0 (7) 13.0 Choice [7]: If you want to initialize Odoo automatically in a specific language, write it here. The format must be ll_CC where ll is the language code and CC is the country code. Examples: en_US, es_ES, es_VE...

odoo_initial_lang? Format: str 🎀 [en_US]: If you are using an OCI/Docker image registry (such as the Docker Hub, Quay or Gitlab registry) to publish the Odoo images that will be built with this Doodba project, specify here the path to the odoo image built with it. Leave it empty if you are not using a registry. Example: docker.io/myteam/example-odoo

odoo_oci_image? Format: str 🎀 [None]: Do you want to list databases publicly?

odoo_listdb? Format: bool 🎀? [Y/n] πŸ’‘ To auto-generate strong passwords, see https://ddg.gg/?q=password+64+strong ⚠️ This password is critical for security, especially if you have set odoo_listdb to true, so keep it safe. What will be your odoo admin password?

odoo_admin_password? Format: str 🎀 [example-admin-password]: Set your Odoo db filter. It must be a regexp that matches the domain name being visited. It is useful if you use Odoo in SaaS mode.

odoo_dbfilter? Format: str 🎀 [.*]: ⚠️ Using a misconfigured proxy for production can create a security hole. Using none can create performance problems. Which proxy will you use to deploy odoo?

odoo_proxy? Format: yaml 🎀 (1) No proxy (dangerous for production) (2) Traefik (3) Other proxy (it's up to you!) Choice [2]: Which PostgreSQL version do you want to deploy?

postgres_version? Format: yaml 🎀 (1) I will use an external PostgreSQL server (2) 9.6 (3) 10 (4) 11 (5) 12 Choice [5]: Which user name will be used to connect to the postgres server?

postgres_username? Format: str 🎀 [odoo13]: πŸ’‘ If database names differ among environments, operations like restoring a database from an alien environment will be harder to maintain, but can provide additional security. It's up to you. We default to "prod" for historical reasons. What is going to be the main database name?

postgres_dbname? Format: str 🎀 [dev13]: What will be your postgres user password?

postgres_password? Format: str 🎀 [example-db-password]: Now, let's start configuring outgoing mail. In case an email coming out from odoo doesn't have a valid From: header address, which address should be the default one that sends the email?

smtp_default_from? Format: str 🎀 [None]: ⚠️ If you leave this answer empty, all next SMTP settings will be ignored. If you supply a valid SMTP host, production Odoo will be able to send emails without needing to configure any ir.mail_server record, because Doodba will configure it to use a mail relay that will manage a local mail queue before sending it to the real SMTP endpoint (saving your mails from bad network conditions). The same relay will be used to send backup reports. So, what is your SMTP host? Example: mail.example.com

smtp_relay_host? Format: str 🎀 [None]: Indicate the port to connect in the SMTP server you just defined. ⚠️ NEVER use port 465 πŸ‘‰ https://github.com/tomav/docker-mailserver/issues/1428

smtp_relay_port? Format: int 🎀 [587]: Indicate the user to connect in the SMTP server you just defined. For Odoo to work fine, this user needs to be able to do mail spoofing.

smtp_relay_user? Format: str 🎀 [None]: What is your SMTP password?

smtp_relay_password? Format: str 🎀 [example-smtp-password]: Usually, if you send mails like "user@example.com", the canonical domain would be "example.com". This canonical domain should have correct SPF, DKIM and DMARC settings that allow the SMTP host to send mails in its name. When Odoo tries to send a mail that does not come from a canonical domain, the domain you indicate here will be used when rewriting the address with SRS (https://en.wikipedia.org/wiki/SRS). What's your canonical domain?

smtp_canonical_default? Format: str 🎀 [None]: Supply a list of other domains authorized to send email from this Odoo instance and SMTP host. They will not be affected by SRS. They also must have valid SPF, DKIM and DMARC settings. You do not need to repeat the canonical domain you indicated above. Example: [examplemail.com, example.org]

smtp_canonical_domains? Format: yaml 🎀 [None]: If you want to use an Amazon S3 bucket, write its URL like s3://s3.amazonaws.com/example-bucket/example/path to make sure it works fine. If you want to use any other backend, supply any URL supported by Duplicity (our choice backup engine; read http://duplicity.nongnu.org/vers8/duplicity.1.html#sect7 for those URL formats). If you don't want bakcups, leave this empty. Where should the backups be stored?

backup_dst? Format: str 🎀 [None]: The backup container will send email reports if the SMTP relay is properly configured. What email address should it use to send them?

backup_email_from? Format: str 🎀 [None]: Where to send those backup reports?

backup_email_to? Format: str 🎀 [None]: If you're using S3, you probably want to delete outdated backups using bucket lifecycle rules. If you use other storage backend, then you probably want to enable outdated backups deletion using duplicity itself. So, do you want to enable duplicity backup deletion via cron?

backup_deletion? Format: bool 🎀? [y/N] Set the timezone used by the backup cron for reports. Visit https://www.cyberciti.biz/faq/linux-unix-set-tz-environment-variable/ to know how to obtain a valid value for this variable.

backup_tz? Format: str 🎀 [UTC]: If you're using AWS S3 to store backups, provide here your access key ID.

backup_aws_access_key_id? Format: str 🎀 [None]: If you're using AWS S3 to store backups, provide here your secret access key.

backup_aws_secret_access_key? Format: str 🎀 [None]: ⚠️ This passphrase is critical for security, so keep it safe. You will need it to restore backups. Which will be your backups passphrase?

backup_passphrase? Format: str 🎀 [example-backup-passphrase]:

Logs

pre-commit installed at .git/hooks/pre-commit Attaching to proyecto13_odoo_proxy_1, proyecto13_odoo_1, proyecto13_cdnjs_cloudflare_proxy_1, proyecto13_gravatar_proxy_1, proyecto13_fonts_gstatic_proxy_1, proyecto13_wdb_1, proyecto13_db_1, proyecto13_smtp_1, proyecto13_fonts_googleapis_proxy_1, proyecto13_google_proxy_1 google_proxy_1 | INFO:root:Resolved www.google.com to 216.58.217.4 google_proxy_1 | INFO:root:Executing: socat tcp-listen:80,fork,reuseaddr tcp-connect:216.58.217.4:80 google_proxy_1 | INFO:root:Executing: socat tcp-listen:443,fork,reuseaddr tcp-connect:216.58.217.4:443 google_proxy_1 | INFO:root:Resolved www.google.com to 172.217.15.4 google_proxy_1 | INFO:root:Executing: socat tcp-listen:80,fork,reuseaddr tcp-connect:172.217.15.4:80 google_proxy_1 | INFO:root:Executing: socat tcp-listen:443,fork,reuseaddr tcp-connect:172.217.15.4:443 odoo_proxy_1 | INFO:root:Executing: socat tcp-listen:6899,fork,reuseaddr tcp-connect:odoo:6899 odoo_proxy_1 | INFO:root:Executing: socat tcp-listen:8069,fork,reuseaddr tcp-connect:odoo:8069 odoo_proxy_1 | INFO:root:Executing: socat tcp-listen:6899,fork,reuseaddr tcp-connect:odoo:6899 odoo_proxy_1 | INFO:root:Executing: socat tcp-listen:8069,fork,reuseaddr tcp-connect:odoo:8069 odoo_proxy_1 | 2020/04/20 17:54:33 socat[9] E connect(5, AF=2 172.21.0.10:8069, 16): Connection refused odoo_proxy_1 | 2020/04/20 17:54:33 socat[10] E connect(5, AF=2 172.21.0.10:8069, 16): Connection refused odoo_proxy_1 | 2020/04/20 17:54:33 socat[11] E connect(5, AF=2 172.21.0.10:8069, 16): Connection refused cdnjs_cloudflare_proxy_1 | INFO:root:Resolved cdnjs.cloudflare.com to 104.16.133.229 cdnjs_cloudflare_proxy_1 | INFO:root:Executing: socat tcp-listen:80,fork,reuseaddr tcp-connect:104.16.133.229:80 cdnjs_cloudflare_proxy_1 | INFO:root:Executing: socat tcp-listen:443,fork,reuseaddr tcp-connect:104.16.133.229:443 cdnjs_cloudflare_proxy_1 | INFO:root:Resolved cdnjs.cloudflare.com to 104.16.133.229 cdnjs_cloudflare_proxy_1 | INFO:root:Executing: socat tcp-listen:80,fork,reuseaddr tcp-connect:104.16.133.229:80 cdnjs_cloudflare_proxy_1 | INFO:root:Executing: socat tcp-listen:443,fork,reuseaddr tcp-connect:104.16.133.229:443 fonts_googleapis_proxy_1 | INFO:root:Resolved fonts.googleapis.com to 216.58.217.10 fonts_googleapis_proxy_1 | INFO:root:Executing: socat tcp-listen:80,fork,reuseaddr tcp-connect:216.58.217.10:80 fonts_googleapis_proxy_1 | INFO:root:Executing: socat tcp-listen:443,fork,reuseaddr tcp-connect:216.58.217.10:443 fonts_googleapis_proxy_1 | INFO:root:Resolved fonts.googleapis.com to 216.58.193.138 fonts_googleapis_proxy_1 | INFO:root:Executing: socat tcp-listen:80,fork,reuseaddr tcp-connect:216.58.193.138:80 fonts_googleapis_proxy_1 | INFO:root:Executing: socat tcp-listen:443,fork,reuseaddr tcp-connect:216.58.193.138:443 fonts_gstatic_proxy_1 | INFO:root:Resolved fonts.gstatic.com to 172.217.7.35 fonts_gstatic_proxy_1 | INFO:root:Executing: socat tcp-listen:80,fork,reuseaddr tcp-connect:172.217.7.35:80 fonts_gstatic_proxy_1 | INFO:root:Executing: socat tcp-listen:443,fork,reuseaddr tcp-connect:172.217.7.35:443 fonts_gstatic_proxy_1 | INFO:root:Resolved fonts.gstatic.com to 216.58.217.3 fonts_gstatic_proxy_1 | INFO:root:Executing: socat tcp-listen:80,fork,reuseaddr tcp-connect:216.58.217.3:80 fonts_gstatic_proxy_1 | INFO:root:Executing: socat tcp-listen:443,fork,reuseaddr tcp-connect:216.58.217.3:443 db_1 | 2020-04-20 14:01:43.863 GMT [1] LOG: database system is shut down db_1 | db_1 | PostgreSQL Database directory appears to contain a database; Skipping initialization db_1 | db_1 | 2020-04-20 17:54:28.222 GMT [1] LOG: starting PostgreSQL 12.2 on x86_64-pc-linux-musl, compiled by gcc (Alpine 9.2.0) 9.2.0, 64-bit db_1 | 2020-04-20 17:54:28.222 GMT [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 db_1 | 2020-04-20 17:54:28.223 GMT [1] LOG: listening on IPv6 address "::", port 5432 db_1 | 2020-04-20 17:54:28.225 GMT [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" db_1 | 2020-04-20 17:54:28.238 GMT [20] LOG: database system was shut down at 2020-04-20 14:01:43 GMT db_1 | 2020-04-20 17:54:28.244 GMT [1] LOG: database system is ready to accept connections gravatar_proxy_1 | INFO:root:Resolved www.gravatar.com to 192.0.73.2 gravatar_proxy_1 | INFO:root:Executing: socat tcp-listen:80,fork,reuseaddr tcp-connect:192.0.73.2:80 gravatar_proxy_1 | INFO:root:Executing: socat tcp-listen:443,fork,reuseaddr tcp-connect:192.0.73.2:443 gravatar_proxy_1 | INFO:root:Resolved www.gravatar.com to 192.0.73.2 gravatar_proxy_1 | INFO:root:Executing: socat tcp-listen:80,fork,reuseaddr tcp-connect:192.0.73.2:80 gravatar_proxy_1 | INFO:root:Executing: socat tcp-listen:443,fork,reuseaddr tcp-connect:192.0.73.2:443 odoo_1 | File "/opt/odoo/custom/src/odoo/odoo/http.py", line 1441, in dispatch odoo_1 | ir_http = request.registry['ir.http'] odoo_1 | File "/opt/odoo/custom/src/odoo/odoo/modules/registry.py", line 177, in getitem odoo_1 | return self.models[model_name] odoo_1 | KeyError: 'ir.http' odoo_1 | 2020-04-20 17:54:35,455 1 INFO ? werkzeug: 172.21.0.11 - - [20/Apr/2020 17:54:35] "GET /?debugger=yes&cmd=resource&f=style.css HTTP/1.1" 200 - - - - odoo_1 | 2020-04-20 17:54:35,457 1 INFO ? werkzeug: 172.21.0.11 - - [20/Apr/2020 17:54:35] "GET /?debugger=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 - - - - odoo_1 | 2020-04-20 17:54:35,459 1 INFO ? werkzeug: 172.21.0.11 - - [20/Apr/2020 17:54:35] "GET /?debugger=yes&cmd=resource&f=jquery.js HTTP/1.1" 200 - - - - odoo_1 | 2020-04-20 17:54:35,575 1 INFO ? werkzeug: 172.21.0.11 - - [20/Apr/2020 17:54:35] "GET /?debugger=yes&cmd=resource&f=console.png HTTP/1.1" 200 - - - - odoo_1 | 2020-04-20 17:54:35,585 1 INFO ? werkzeug: 172.21.0.11 - - [20/Apr/2020 17:54:35] "GET /?debugger=yes&cmd=resource&f=console.png HTTP/1.1" 200 - - - - smtp_1 | Creating API v1 with WebPath: smtp_1 | Creating API v2 with WebPath: smtp_1 | [APIv1] KEEPALIVE /api/v1/events smtp_1 | [APIv1] KEEPALIVE /api/v1/events smtp_1 | 2020/04/20 17:54:29 Using in-memory storage smtp_1 | 2020/04/20 17:54:29 [SMTP] Binding to address: 0.0.0.0:1025 smtp_1 | 2020/04/20 17:54:29 Serving under http://0.0.0.0:8025/ smtp_1 | [HTTP] Binding to address: 0.0.0.0:8025 smtp_1 | Creating API v1 with WebPath: smtp_1 | Creating API v2 with WebPath: smtp_1 | [APIv1] KEEPALIVE /api/v1/events db_1 | 2020-04-20 17:55:33.883 GMT [30] ERROR: relation "ir_module_module" does not exist at character 28 db_1 | 2020-04-20 17:55:33.883 GMT [30] STATEMENT: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | 2020-04-20 17:55:33,883 1 ERROR devel odoo.sql_db: bad query: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | ERROR: relation "ir_module_module" does not exist odoo_1 | LINE 1: SELECT latest_version FROM ir_module_module WHERE name='base... odoo_1 | ^ odoo_1 |
odoo_1 | 2020-04-20 17:55:33,884 1 WARNING ? odoo.addons.base.models.ir_cron: Tried to poll an undefined table on database devel. db_1 | 2020-04-20 17:55:34.935 GMT [30] ERROR: relation "ir_module_module" does not exist at character 28 db_1 | 2020-04-20 17:55:34.935 GMT [30] STATEMENT: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | 2020-04-20 17:55:34,935 1 ERROR devel odoo.sql_db: bad query: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | ERROR: relation "ir_module_module" does not exist odoo_1 | LINE 1: SELECT latest_version FROM ir_module_module WHERE name='base... odoo_1 | ^ odoo_1 |
odoo_1 | 2020-04-20 17:55:34,936 1 WARNING ? odoo.addons.base.models.ir_cron: Tried to poll an undefined table on database devel. smtp_1 | [APIv1] KEEPALIVE /api/v1/events db_1 | 2020-04-20 17:56:33.942 GMT [30] ERROR: relation "ir_module_module" does not exist at character 28 db_1 | 2020-04-20 17:56:33.942 GMT [30] STATEMENT: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | 2020-04-20 17:56:33,943 1 ERROR devel odoo.sql_db: bad query: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | ERROR: relation "ir_module_module" does not exist odoo_1 | LINE 1: SELECT latest_version FROM ir_module_module WHERE name='base... odoo_1 | ^ odoo_1 |
odoo_1 | 2020-04-20 17:56:33,943 1 WARNING ? odoo.addons.base.models.ir_cron: Tried to poll an undefined table on database devel. db_1 | 2020-04-20 17:56:35.995 GMT [30] ERROR: relation "ir_module_module" does not exist at character 28 db_1 | 2020-04-20 17:56:35.995 GMT [30] STATEMENT: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | 2020-04-20 17:56:35,995 1 ERROR devel odoo.sql_db: bad query: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | ERROR: relation "ir_module_module" does not exist odoo_1 | LINE 1: SELECT latest_version FROM ir_module_module WHERE name='base... odoo_1 | ^ odoo_1 |
odoo_1 | 2020-04-20 17:56:35,996 1 WARNING ? odoo.addons.base.models.ir_cron: Tried to poll an undefined table on database devel. smtp_1 | [APIv1] KEEPALIVE /api/v1/events db_1 | 2020-04-20 17:57:33.947 GMT [30] ERROR: relation "ir_module_module" does not exist at character 28 db_1 | 2020-04-20 17:57:33.947 GMT [30] STATEMENT: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | 2020-04-20 17:57:33,947 1 ERROR devel odoo.sql_db: bad query: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | ERROR: relation "ir_module_module" does not exist odoo_1 | LINE 1: SELECT latest_version FROM ir_module_module WHERE name='base... odoo_1 | ^ odoo_1 |
odoo_1 | 2020-04-20 17:57:33,948 1 WARNING ? odoo.addons.base.models.ir_cron: Tried to poll an undefined table on database devel. db_1 | 2020-04-20 17:57:37.058 GMT [30] ERROR: relation "ir_module_module" does not exist at character 28 db_1 | 2020-04-20 17:57:37.058 GMT [30] STATEMENT: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | 2020-04-20 17:57:37,059 1 ERROR devel odoo.sql_db: bad query: SELECT latest_version FROM ir_module_module WHERE name='base' odoo_1 | ERROR: relation "ir_module_module" does not exist odoo_1 | LINE 1: SELECT latest_version FROM ir_module_module WHERE name='base... odoo_1 | ^ odoo_1 |
odoo_1 | 2020-04-20 17:57:37,059 1 WARNING ? odoo.addons.base.models.ir_cron: Tried to poll an undefined table on database devel.

carlosecv commented 4 years ago

image

theangryangel commented 4 years ago

Sounds like you’ve got a blank DB, drop it and you should be good

yajo commented 4 years ago

Yeah, this is Odoo's problem, not ours.

Just do docker-compose run --rm odoo --stop-after-init -i base and let it create one for you.

carlosecv commented 4 years ago

Thank you Yaho it worked

docker-compose run --rm odoo --stop-after-init -i base then invoke restart

Sorry Im too newbie to catch this basic errors.

yajo commented 4 years ago

Sorry Im too newbie to catch this basic errors.

Being newbie has one advantage: you're best to help new future newbies, because you're the best ones to understand other newbies' problems :smiley:

So please consider to add this to the FAQ. PRs welcome.

carlosecv commented 4 years ago

Where do i can contribute to the FAQ?

yajo commented 4 years ago

It's this file: https://github.com/Tecnativa/doodba-copier-template/blob/master/docs/faq.md

You can open a PR as usual: https://opensource.guide/how-to-contribute/#opening-a-pull-request

carlosecv commented 4 years ago

It seems to me that we can create a quick guide so that it is not so painful to start using the copier, for newer users who do not have much of the necessary experience but who have other knowledge that can enrich the project.

Do you think I can do a PR to create this guide and could be useful for the project?

"Quick steps to copier"

Or do i add it to FAQ "Quick steps to copier"

JDamour commented 4 years ago

Indeed @carlosecv it will be helpful for new users

yajo commented 4 years ago

Yes, you can, but it's not our goal to document other tools. When you use copier, docker-compose, odoo, git, docker... you are supposed to know those tools. If you don't, you should consult those projects' docs.

Our docs must focus on our project.

If the guide is short and directs users to upstream docs, I have no problem on including it, though.

If you find upstream docs not so helpful, then you probably should contact upstream on that subject. Regarding copier itself, there's a WIP on improving its docs in https://github.com/pykong/copier/pull/203.