Skip to content

Stdlib glob #182

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [ master ]
branches: [ main ]
pull_request:
branches: [ master ]
branches: [ main ]
schedule:
- cron: '0 2 * * 1-5'

Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTE.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ If it is large, such as suggesting a new repository, sub-repository, or interfac
### Your First Code Contribution

If you are a new contributor, *thank you!*
Before your first merge, you will need to be added to the [CONTRIBUTORS](https://github.com/go-python/license/blob/master/CONTRIBUTORS) and [AUTHORS](https://github.com/go-python/license/blob/master/AUTHORS) files.
Before your first merge, you will need to be added to the [CONTRIBUTORS](https://github.com/go-python/license/blob/main/CONTRIBUTORS) and [AUTHORS](https://github.com/go-python/license/blob/main/AUTHORS) files.
Open a pull request adding yourself to these files.
All `go-python` code follows the BSD license in the [license document](https://github.com/go-python/license/blob/master/LICENSE).
All `go-python` code follows the BSD license in the [license document](https://github.com/go-python/license/blob/main/LICENSE).
We prefer that code contributions do not come with additional licensing.
For exceptions, added code must also follow a BSD license.

Expand Down Expand Up @@ -88,7 +88,7 @@ Please always format your code with [goimports](https://godoc.org/golang.org/x/t
Best is to have it invoked as a hook when you save your `.go` files.

Files in the `go-python` repository don't list author names, both to avoid clutter and to avoid having to keep the lists up to date.
Instead, your name will appear in the change log and in the [CONTRIBUTORS](https://github.com/go-python/license/blob/master/CONTRIBUTORS) and [AUTHORS](https://github.com/go-python/license/blob/master/AUTHORS) files.
Instead, your name will appear in the change log and in the [CONTRIBUTORS](https://github.com/go-python/license/blob/main/CONTRIBUTORS) and [AUTHORS](https://github.com/go-python/license/blob/main/AUTHORS) files.

New files that you contribute should use the standard copyright header:

Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# gpython

[![Build Status](https://github.com/go-python/gpython/workflows/CI/badge.svg)](https://github.com/go-python/gpython/actions)
[![codecov](https://codecov.io/gh/go-python/gpython/branch/master/graph/badge.svg)](https://codecov.io/gh/go-python/gpython)
[![codecov](https://codecov.io/gh/go-python/gpython/branch/main/graph/badge.svg)](https://codecov.io/gh/go-python/gpython)
[![GoDoc](https://godoc.org/github.com/go-python/gpython?status.svg)](https://godoc.org/github.com/go-python/gpython)
[![License](https://img.shields.io/badge/License-BSD--3-blue.svg)](https://github.com/go-python/gpython/blob/master/LICENSE)
[![License](https://img.shields.io/badge/License-BSD--3-blue.svg)](https://github.com/go-python/gpython/blob/main/LICENSE)

gpython is a part re-implementation, part port of the Python 3.4
interpreter in Go. Although there are many areas of improvement,
Expand Down Expand Up @@ -54,7 +54,7 @@ gpython currently:
- Supports concurrent multi-interpreter ("multi-context") execution

Speed hasn't been a goal of the conversions however it runs pystone at
about 20% of the speed of CPython. A [π computation test](https://github.com/go-python/gpython/tree/master/examples/pi_chudnovsky_bs.py) runs quicker under
about 20% of the speed of CPython. A [π computation test](https://github.com/go-python/gpython/tree/main/examples/pi_chudnovsky_bs.py) runs quicker under
gpython as the Go long integer primitives are likely faster than the
Python ones.

Expand All @@ -63,15 +63,15 @@ you know would be interested to take it futher, it would be much appreciated.

## Getting Started

The [embedding example](https://github.com/go-python/gpython/tree/master/examples/embedding) demonstrates how to
The [embedding example](https://github.com/go-python/gpython/tree/main/examples/embedding) demonstrates how to
easily embed and invoke gpython from any Go application.

Of interest, gpython is able to run multiple interpreter instances simultaneously,
allowing you to embed gpython naturally into your Go application. This makes it
possible to use gpython in a server situation where complete interpreter
independence is paramount. See this in action in the [multi-context example](https://github.com/go-python/gpython/tree/master/examples/multi-context).
independence is paramount. See this in action in the [multi-context example](https://github.com/go-python/gpython/tree/main/examples/multi-context).

If you are looking to get involved, a light and easy place to start is adding more convenience functions to [py/util.go](https://github.com/go-python/gpython/tree/master/py/util.go). See [notes.txt](https://github.com/go-python/gpython/blob/master/notes.txt) for bigger ideas.
If you are looking to get involved, a light and easy place to start is adding more convenience functions to [py/util.go](https://github.com/go-python/gpython/tree/main/py/util.go). See [notes.txt](https://github.com/go-python/gpython/blob/main/notes.txt) for bigger ideas.


## Other Projects of Interest
Expand All @@ -88,4 +88,4 @@ or on the [Gophers Slack](https://gophers.slack.com/) in the `#go-python` channe

This is licensed under the MIT licence, however it contains code which
was ported fairly directly directly from the CPython source code under
the [PSF LICENSE](https://github.com/python/cpython/blob/master/LICENSE).
the [PSF LICENSE](https://github.com/python/cpython/blob/main/LICENSE).
4 changes: 2 additions & 2 deletions examples/embedding/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,5 @@ Spring Break itinerary:
- `main.go` demonstrates high-level convenience functions such as `py.RunFile()`.
- Embedding a Go `struct` as a Python object only requires that it implement `py.Object`, which is a single function:
`Type() *py.Type`
- See [py/run.go](https://github.com/go-python/gpython/tree/master/py/run.go) for more about interpreter instances and `py.Context`
- Helper functions are available in [py/util.go](https://github.com/go-python/gpython/tree/master/py/util.go) and your contributions are welcome!
- See [py/run.go](https://github.com/go-python/gpython/tree/main/py/run.go) for more about interpreter instances and `py.Context`
- Helper functions are available in [py/util.go](https://github.com/go-python/gpython/tree/main/py/util.go) and your contributions are welcome!
34 changes: 34 additions & 0 deletions py/bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,43 @@ func (a Bytes) M__iadd__(other Object) (Object, error) {
return NotImplemented, nil
}

func (a Bytes) Replace(args Tuple) (Object, error) {
var (
pyold Object = None
pynew Object = None
pycnt Object = Int(-1)
)
err := ParseTuple(args, "yy|i:replace", &pyold, &pynew, &pycnt)
if err != nil {
return nil, err
}

var (
old = []byte(pyold.(Bytes))
new = []byte(pynew.(Bytes))
cnt = int(pycnt.(Int))
)

return Bytes(bytes.Replace([]byte(a), old, new, cnt)), nil
}

// Check interface is satisfied
var (
_ richComparison = (Bytes)(nil)
_ I__add__ = (Bytes)(nil)
_ I__iadd__ = (Bytes)(nil)
)

func init() {
BytesType.Dict["replace"] = MustNewMethod("replace", func(self Object, args Tuple) (Object, error) {
return self.(Bytes).Replace(args)
}, 0, `replace(self, old, new, count=-1) -> return a copy with all occurrences of substring old replaced by new.

count
Maximum number of occurrences to replace.
-1 (the default value) means replace all occurrences.

If the optional argument count is given, only the first count occurrences are
replaced.`)

}
31 changes: 31 additions & 0 deletions py/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,17 @@ func fieldsN(s string, n int) []string {
}

func init() {
StringType.Dict["replace"] = MustNewMethod("replace", func(self Object, args Tuple) (Object, error) {
return self.(String).Replace(args)
}, 0, `replace(self, old, new, count=-1) -> return a copy with all occurrences of substring old replaced by new.

count
Maximum number of occurrences to replace.
-1 (the default value) means replace all occurrences.

If the optional argument count is given, only the first count occurrences are
replaced.`)

StringType.Dict["split"] = MustNewMethod("split", func(self Object, args Tuple, kwargs StringDict) (Object, error) {
return self.(String).Split(args, kwargs)
}, 0, "split(sub) -> split string with sub.")
Expand Down Expand Up @@ -598,6 +609,26 @@ func (s String) Split(args Tuple, kwargs StringDict) (Object, error) {
return &o, nil
}

func (s String) Replace(args Tuple) (Object, error) {
var (
pyold Object = None
pynew Object = None
pycnt Object = Int(-1)
)
err := ParseTuple(args, "ss|i:replace", &pyold, &pynew, &pycnt)
if err != nil {
return nil, err
}

var (
old = string(pyold.(String))
new = string(pynew.(String))
cnt = int(pycnt.(Int))
)

return String(strings.Replace(string(s), old, new, cnt)), nil
}

// Check stringerface is satisfied
var (
_ richComparison = String("")
Expand Down
64 changes: 64 additions & 0 deletions stdlib/glob/glob.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2022 The go-python Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package glob provides the implementation of the python's 'glob' module.
package glob

import (
"path/filepath"

"github.com/go-python/gpython/py"
)

func init() {
py.RegisterModule(&py.ModuleImpl{
Info: py.ModuleInfo{
Name: "glob",
Doc: "Filename globbing utility.",
},
Methods: []*py.Method{
py.MustNewMethod("glob", glob, 0, glob_doc),
},
})
}

const glob_doc = `Return a list of paths matching a pathname pattern.
The pattern may contain simple shell-style wildcards a la
fnmatch. However, unlike fnmatch, filenames starting with a
dot are special cases that are not matched by '*' and '?'
patterns.`

func glob(self py.Object, args py.Tuple) (py.Object, error) {
var (
pypathname py.Object
)
err := py.ParseTuple(args, "s*:glob", &pypathname)
if err != nil {
return nil, err
}

var (
pathname string
cnv func(v string) py.Object
)
switch n := pypathname.(type) {
case py.String:
pathname = string(n)
cnv = func(v string) py.Object { return py.String(v) }
case py.Bytes:
pathname = string(n)
cnv = func(v string) py.Object { return py.Bytes(v) }
}
matches, err := filepath.Glob(pathname)
if err != nil {
return nil, err
}

lst := py.List{Items: make([]py.Object, len(matches))}
for i, v := range matches {
lst.Items[i] = cnv(v)
}

return &lst, nil
}
15 changes: 15 additions & 0 deletions stdlib/glob/glob_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2022 The go-python Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package glob_test

import (
"testing"

"github.com/go-python/gpython/pytest"
)

func TestGlob(t *testing.T) {
pytest.RunScript(t, "./testdata/test.py")
}
58 changes: 58 additions & 0 deletions stdlib/glob/testdata/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright 2022 The go-python Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

import glob

def norm(vs):
if len(vs) == 0:
return vs
if type(vs[0]) == type(""):
return normStr(vs)
return normBytes(vs)

def normStr(vs):
from os import sep
x = []
for v in vs:
x.append(v.replace('/', sep))
return x

def normBytes(vs):
from os import sep
x = []
for v in vs:
x.append(v.replace(b'/', bytes(sep, encoding="utf-8")))
return x

def assertEqual(x, y):
xx = norm(x)
yy = norm(y)
assert xx == yy, "got: %s, want: %s" % (repr(x), repr(y))


## test strings
assertEqual(glob.glob('*'), ["glob.go", "glob_test.go", "testdata"])
assertEqual(glob.glob('*test*'), ["glob_test.go", "testdata"])
assertEqual(glob.glob('*/test*'), ["testdata/test.py", "testdata/test_golden.txt"])
assertEqual(glob.glob('*/test*_*'), ["testdata/test_golden.txt"])
assertEqual(glob.glob('*/t??t*_*'), ["testdata/test_golden.txt"])
assertEqual(glob.glob('*/t[e]?t*_*'), ["testdata/test_golden.txt"])
assertEqual(glob.glob('*/t[oe]?t*_*'), ["testdata/test_golden.txt"])
assertEqual(glob.glob('*/t[o]?t*_*'), [])

## FIXME(sbinet)
## assertEqual(glob.glob('*/t[!o]?t*_*'), ["testdata/test_golden.txt"])

## test bytes
assertEqual(glob.glob(b'*'), [b"glob.go", b"glob_test.go", b"testdata"])
assertEqual(glob.glob(b'*test*'), [b"glob_test.go", b"testdata"])
assertEqual(glob.glob(b'*/test*'), [b"testdata/test.py", b"testdata/test_golden.txt"])
assertEqual(glob.glob(b'*/test*_*'), [b"testdata/test_golden.txt"])
assertEqual(glob.glob(b'*/t??t*_*'), [b"testdata/test_golden.txt"])
assertEqual(glob.glob(b'*/t[e]?t*_*'), [b"testdata/test_golden.txt"])
assertEqual(glob.glob(b'*/t[oe]?t*_*'), [b"testdata/test_golden.txt"])
assertEqual(glob.glob(b'*/t[o]?t*_*'), [])

## FIXME(sbinet)
## assertEqual(glob.glob(b'*/t[!o]?t*_*'), [b"testdata/test_golden.txt"])
Empty file.
1 change: 1 addition & 0 deletions stdlib/stdlib.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

_ "github.com/go-python/gpython/stdlib/binascii"
_ "github.com/go-python/gpython/stdlib/builtin"
_ "github.com/go-python/gpython/stdlib/glob"
_ "github.com/go-python/gpython/stdlib/math"
_ "github.com/go-python/gpython/stdlib/os"
_ "github.com/go-python/gpython/stdlib/string"
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy